Skip to content

Any plans to support jsonrpsee? #33

@jakerumbles

Description

@jakerumbles

I've been trying to use this as tower middleware in a jsonrpsee server, and it works fine until I get to server.start() where the GovernorLayer has missing trait implementations. I thought it should work as it's supposed to be tower compatible, but maybe there is some specific jsonrpsee part of the equation here. For reference, I'm able to get the out-of-the-box Tower .rate_limit(3, Duration::from_secs(60)) middleware layer working just fine, but as soon as I try to use GovernorLayer instead it breaks due to missing trait implementations.

My code:

use anyhow::Result;
// use jsonrpsee::server::stop_channel;
use jsonrpsee::server::RpcModule;
// use jsonrpsee::server::RpcServiceBuilder;
use jsonrpsee::server::ServerHandle;
// use jsonrpsee::server::TowerService;
// use jsonrpsee::server::TowerServiceBuilder;
use jsonrpsee::server::{Server, ServerBuilder};
// use rate_limiting::{Rate, RateLimit};
use std::sync::Arc;
use std::time::Duration;
use tower::ServiceBuilder;
use tower_governor::{governor::GovernorConfigBuilder, GovernorLayer};

    pub async fn start(&self) -> Result<RpcServerHandle> {
        // Allow bursts with up to five requests per IP address
        // and replenishes one element every two seconds
        // We Box it because Axum 0.6 requires all Layers to be Clone
        // and thus we need a static reference to it
        let governor_conf = Arc::new(
            GovernorConfigBuilder::default()
                .per_second(2)
                .burst_size(5)
                .finish()
                .unwrap(),
        );

        let governor_limiter = governor_conf.limiter().clone();
        let interval = Duration::from_secs(60);
        // a separate background task to clean up
        std::thread::spawn(move || loop {
            std::thread::sleep(interval);
            tracing::info!("rate limiting storage size: {}", governor_limiter.len());
            governor_limiter.retain_recent();
        });

        // Add rate limiter middleware
        // let rpc_middleware = RpcServiceBuilder::new().layer_fn(
        //     |service: jsonrpsee::server::middleware::rpc::RpcService| {
        //         tracing::info!("MIDDLEWARE: RATE LIMITING");
        //         RateLimit::new(
        //             service,
        //             Rate {
        //                 num: 1,
        //                 period: Duration::from_secs(15),
        //             },
        //         )
        //     },
        // );

        let http_middleware = ServiceBuilder::new()
            // .rate_limit(3, Duration::from_secs(60));
            .layer(GovernorLayer {
                config: governor_conf,
            });

        // let (stop_handle, handle) = stop_channel();

        // let new_server = ServerBuilder::new()
        //     .set_http_middleware(http_middleware)
        //     // .to_service_builder()
        //     // .build(self.rpc_module.clone(), stop_handle);
        //     .build(self.settings.http_listen_addr())
        //     .await?;

        let server = Server::builder()
            // .set_rpc_middleware(middleware)
            .set_http_middleware(http_middleware)
            .build(self.settings.http_listen_addr())
            .await?;

        let addr = server.local_addr()?;
        tracing::info!("RPC server started at: {}", addr);

        let handle = server.start(self.rpc_module.clone());

        Ok(RpcServerHandle {
            listen_addr: addr,
            handle,
        })
    }

Here's the error on server.start()

the method `start` exists for struct `Server<Stack<GovernorLayer<PeerIpKeyExtractor, NoOpMiddleware<QuantaInstant>>, Identity>>`, but its trait bounds were not satisfied
the full type name has been written to '/Users/jake-dev/Github/drosera/crates/target/debug/deps/drosera_services-cbadea97acc5bca2.long-type-5025332530578171701.txt'
consider using `--verbose` to print the full type name to the console
the following trait bounds were not satisfied:
`<Governor<PeerIpKeyExtractor, governor::middleware::NoOpMiddleware<governor::clock::quanta::QuantaInstant>, jsonrpsee::jsonrpsee_server::server::TowerServiceNoHttp<tower::layer::util::Identity>> as Service<tonic::codegen::http::request::Request<tonic::transport::Body>>>::Response = tonic::codegen::http::response::Response<_>`
`<Governor<PeerIpKeyExtractor, governor::middleware::NoOpMiddleware<governor::clock::quanta::QuantaInstant>, jsonrpsee::jsonrpsee_server::server::TowerServiceNoHttp<tower::layer::util::Identity>> as Service<tonic::codegen::http::request::Request<tonic::transport::Body>>>::Error = std::boxed::Box<(dyn StdError + std::marker::Send + std::marker::Sync + 'static)>`
`Governor<PeerIpKeyExtractor, governor::middleware::NoOpMiddleware<governor::clock::quanta::QuantaInstant>, jsonrpsee::jsonrpsee_server::server::TowerServiceNoHttp<tower::layer::util::Identity>>: Service<tonic::codegen::http::request::Request<tonic::transport::Body>>`rustc[Click for full compiler diagnostic](rust-analyzer-diagnostics-view:/diagnostic%20message%20%5B2%5D?2#file%3A%2F%2F%2FUsers%2Fjake-dev%2FGithub%2Fdrosera%2Fcrates%2Fservices%2Fsrc%2Fnetwork%2Frpc%2Fmod.rs)
governor.rs(324, 1): doesn't satisfy `<_ as Service<Request<Body>>>::Error = Box<dyn Error + Send + Sync>`, `<_ as Service<Request<Body>>>::Response = Response<_>` or `_: Service<Request<Body>>`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions