use std::convert::Infallible;
use futures::{future, TryFutureExt};
use hyper::server::{conn::AddrIncoming, Builder};
use tokio::sync::oneshot;
use tracing::{info, warn};
use warp::Filter;
use super::{filters, ReactorEventT};
use crate::effect::EffectBuilder;
pub(super) async fn run<REv: ReactorEventT>(
builder: Builder<AddrIncoming>,
effect_builder: EffectBuilder<REv>,
shutdown_receiver: oneshot::Receiver<()>,
) {
let rest_status = filters::create_status_filter(effect_builder);
let rest_metrics = filters::create_metrics_filter(effect_builder);
let service = warp_json_rpc::service(rest_status.or(rest_metrics));
let make_svc =
hyper::service::make_service_fn(move |_| future::ok::<_, Infallible>(service.clone()));
let server = builder.serve(make_svc);
info!(address = %server.local_addr(), "started REST server");
let _ = server
.with_graceful_shutdown(async {
shutdown_receiver.await.ok();
})
.map_err(|error| {
warn!(%error, "error running REST server");
})
.await;
}