paritytech / jsonrpc

Rust JSON-RPC implementation
MIT License
791 stars 274 forks source link

How to asynchronously process a request in the middleware? #666

Closed kpears201 closed 2 years ago

kpears201 commented 2 years ago

Boiled down my code to something simple. I cannot figure out how I can have an asynchronous decision on whether to return a response or continue on to rpc handlers using next

pub struct SampleMiddleware;
impl Middleware<Meta> for SampleMiddleware {
    type Future = FutureResponse;
    type CallFuture = middleware::NoopCallFuture;

    fn on_request<F, X>(&self, request: Request, meta: Meta, next: F) -> Either<Self::Future, X>
    where
        F: FnOnce(Request, Meta) -> X + Send,
        X: Future<Output = Option<Response>> + Send + 'static,
    {
        Either::Left(Box::pin(SampleMiddleware::process_async(request, meta, next)))
    }
}

impl SampleMiddleware {
    async fn process_async<F, X>(req: Request, meta: Meta, next: F) -> Option<Response>
    where
        F: FnOnce(Request, Meta) -> X + Send,
        X: Future<Output = Option<Response>> + Send + 'static,
    {
        let result = SampleMiddleware::async_fn(&req, &meta).await;
        match result {
            Some(r) => {
                Some(r)
            },
            None => {
                next(req, meta).await
            }
        }
    }

    async fn async_fn(req: &Request, meta: &Meta) -> Option<Response>
    {
        return None
    }
}

On this line: Either::Left(Box::pin(SampleMiddleware::process_async(request, meta, next))), I get:

the parameter type `F` may not live long enough
...so that the type `impl futures::Future<Output = std::option::Option<jsonrpc_core::Response>>` will meet its required lifetime bounds
consider adding an explicit lifetime bound...: `F: 'static`