use std::{
convert::Infallible,
io::{Error, ErrorKind, Result},
net::SocketAddr,
};
use http::{Request, Response};
use hyper::Body;
use jsonrpc_core::futures::FutureExt;
use tokio::sync::broadcast::Receiver;
use tonic::{body::BoxBody, transport::NamedService};
use tower_service::Service;
pub struct Server {
pub stop_ch: Receiver<()>,
pub addr: SocketAddr,
}
impl Server {
pub fn new(addr: SocketAddr, stop_ch: Receiver<()>) -> Self {
Self { stop_ch, addr }
}
}
impl Server {
pub fn serve<S>(mut self, svc: S) -> Result<()>
where
S: Service<Request<Body>, Response = Response<BoxBody>, Error = Infallible>
+ NamedService
+ Clone
+ Send
+ 'static,
S::Future: Send + 'static,
{
tokio::spawn(async move {
avalanche_proto::grpcutil::default_server()
.add_service(svc)
.serve_with_shutdown(self.addr, self.stop_ch.recv().map(|_| ()))
.await
.map_err(|e| Error::new(ErrorKind::Other, format!("grpc server failed: {:?}", e)))
});
log::info!("gRPC server started: {}", self.addr);
Ok(())
}
}