You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So after upgrading hyper to v1.0 users may run into rust-lang/rust#102211 where the error type can't be deduced to Box<std::error::Error + Send Sync + 'static
For instance when using the tower::service_fn such as:
let svc = tower::service_fn(move |req| {let stop_handle = stop_handle2.clone();let svc_builder = svc_builder2.clone();let methods = methods2.clone();letmut svc = svc_builder.build(methods, stop_handle.clone());// It's not possible to know whether the websocket upgrade handshake failed or not here.let is_websocket = ws::is_upgrade_request(&req);if is_websocket {println!("websocket")}else{println!("http")}// This won't work without converting the error to a concrete error....asyncmove{ svc.call(req).await.map_err(|e| anyhow::anyhow!("{:?}", e))}});
This tower:service_fn is recommended because dealing with the trait bounds for the service itself is hard and tricky
but it's also possible to wrap the TowerService/TowerServiceBuilder in a new type with code like this:
#[derive(Clone)]structSvc<RpcMiddleware,HttpMiddleware>{svc_builder:TowerServiceBuilder<RpcMiddleware,HttpMiddleware>,methods:Methods,stop_handle:StopHandle,metrics:Metrics,}impl<RpcMiddleware,HttpMiddleware,B> tower::Service<HttpRequest<B>>forSvc<RpcMiddleware,HttpMiddleware>whereRpcMiddleware:for<'a> tower::Layer<RpcService>Send + Clone,
<RpcMiddlewareas tower::Layer<RpcService>>::Service:Send + Sync + 'static,for<'a> <RpcMiddlewareas tower::Layer<RpcService>>::Service:RpcServiceT<'a>,HttpMiddleware: tower::Layer<TowerServiceNoHttp<RpcMiddleware>> + Send + 'static + Clone,
<HttpMiddlewareas tower::Layer<TowerServiceNoHttp<RpcMiddleware>>>::Service:Send + tower::Service<HttpRequest<B>,Response = HttpResponse,Error = BoxError>,
<<HttpMiddlewareas tower::Layer<TowerServiceNoHttp<RpcMiddleware>>>::Serviceas tower::Service<HttpRequest<B>>>::Future:Send + 'static,B: http_body::Body<Data = hyper::body::Bytes> + Send + 'static,B::Error:Into<BoxError>,{typeError = BoxError;typeResponse = HttpResponse;typeFuture = Pin<Box<dynFuture<Output = Result<Self::Response,Self::Error>> + Send>>;fncall(&mutself,req:HttpRequest<B>) -> Self::Future{let is_websocket = jsonrpsee::server::ws::is_upgrade_request(&req);let transport_label = if is_websocket {"ws"}else{"http"};let metrics = self.metrics.clone();letmut svc = self.svc_builder.clone().build(self.methods.clone(),self.stop_handle.clone());if is_websocket {// Utilize the session close future to know when the actual WebSocket// session was closed.let session_close = svc.on_session_closed();// A little bit weird API but the response to HTTP request must be returned below// and we spawn a task to register when the session is closed.
tokio::spawn(asyncmove{
session_close.await;
tracing::info!("Closed WebSocket connection");
metrics.closed_ws_connections.fetch_add(1,Ordering::Relaxed);});asyncmove{
tracing::info!("Opened WebSocket connection");
metrics.opened_ws_connections.fetch_add(1,Ordering::Relaxed);
svc.call(req).await}.boxed()}else{// HTTP.asyncmove{
tracing::info!("Opened HTTP connection");
metrics.http_calls.fetch_add(1,Ordering::Relaxed);let rp = svc.call(req).await;if rp.is_ok(){
metrics.success_http_calls.fetch_add(1,Ordering::Relaxed);}
tracing::info!("Closed HTTP connection");
rp
}.boxed()}}fnpoll_ready(&mutself,_cx:&mut std::task::Context<'_>) -> std::task::Poll<Result<(),Self::Error>>{Poll::Ready(Ok(()))}}
So, the question is really if we should re-export TowerNoHttpService and add an example with this mess?
Maybe it's possible to simplify the trait bounds somehow?
So after upgrading hyper to v1.0 users may run into rust-lang/rust#102211 where the error type can't be deduced to
Box<std::error::Error + Send Sync + 'static
For instance when using the
tower::service_fn
such as:This
tower:service_fn
is recommended because dealing with the trait bounds for the service itself is hard and trickybut it's also possible to wrap the TowerService/TowerServiceBuilder in a new type with code like this:
So, the question is really if we should re-export TowerNoHttpService and add an example with this mess?
Maybe it's possible to simplify the trait bounds somehow?
//cc @jsdw @lexnv
The text was updated successfully, but these errors were encountered: