benwis / tower-governor

Rate Limiting middleware for Tower/Axum/Tonic/Hyper utilizing the governor crate
MIT License
174 stars 29 forks source link

Any example using tonic? #15

Open esemeniuc opened 9 months ago

esemeniuc commented 9 months ago

Trying to use this with tonic:

pub fn ip_rate_limiter() -> GovernorLayer<'static, PeerIpKeyExtractor, NoOpMiddleware> {
    // 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 = Box::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();
    });
    GovernorLayer {
        // We can leak this because it is created once and then
        config: Box::leak(governor_conf),
    }
}
    let middlewares = tower::ServiceBuilder::new()
        // .timeout(Duration::from_secs(10))
        // .concurrency_limit(1_000)
        .layer(ip_rate_limiter())
        .into_inner();

    info!("starting grpc server at {socket_addr}");
    Server::builder()
        .layer(middlewares)
        .await
        .serve(socket_addr)
        .expect("server to start");

I get the following error:

error[E0277]: the trait bound `tower_governor::governor::Governor<tower_governor::key_extractor::PeerIpKeyExtractor, governor::middleware::NoOpMiddleware<governor::clock::quanta::QuantaInstant>, Routes>: Service<request::Request<tonic::transport::Body>>` is not satisfied
   --> src/auth_service/src/main.rs:245:10
    |
245 |         .serve(socket_addr)
    |          ^^^^^ the trait `Service<request::Request<tonic::transport::Body>>` is not implemented for `tower_governor::governor::Governor<tower_governor::key_extractor::PeerIpKeyExtractor, governor::middleware::NoOpMiddleware<governor::clock::quanta::QuantaInstant>, Routes>`
    |
    = help: the following other types implement trait `Service<Request>`:
              tower_governor::governor::Governor<K, governor::middleware::NoOpMiddleware, S>
              tower_governor::governor::Governor<K, governor::middleware::StateInformationMiddleware, S>
    = note: required for `InterceptedService<tower_governor::governor::Governor<tower_governor::key_extractor::PeerIpKeyExtractor, governor::middleware::NoOpMiddleware<governor::clock::quanta::QuantaInstant>, Routes>, HealthChecker>` to implement `Service<request::Request<tonic::transport::Body>>`
benwis commented 9 months ago

I can's say that I have one, although it sounds like there's some work to do to be compatible with tonic's types

mandrush commented 14 hours ago

Hey, are there any plans of adding tonic support in any forseeable future? What would be required to do in order to add this kind of support? Is this a matter of adding this to tower-governor, or rather to governor?