Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add
DefaultTimeoutService
to set default timeouts per route
This also makes turborepo respect the client's preferred timeout also, rather than defaulting to 100ms across the board.
- Loading branch information
Alexander Lyon
authored and
Alexander Lyon
committed
Feb 20, 2024
1 parent
9046991
commit e365d7c
Showing
5 changed files
with
108 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
//! default timeout layer | ||
//! | ||
//! This module provides some basic middleware that aims to | ||
//! improve the flexibility of the daemon server by doing | ||
//! two things: | ||
//! | ||
//! a) remove the server-wide timeout of 100ms in favour of | ||
//! a less aggressive 30s. the way tonic works is the | ||
//! lowest timeout (server vs request-specific) is always | ||
//! used meaning clients' timeout requests were ignored | ||
//! if set to >100ms | ||
//! b) add a middleware to reinstate the timeout, if the | ||
//! client does not specify it, defaulting to 100ms for | ||
//! 'non-blocking' calls (requests in the hot path for | ||
//! a run of turbo), and falling back to the server | ||
//! limit for blocking ones (useful in cases like the | ||
//! LSP) | ||
//! | ||
//! With this in place, it means that clients can specify | ||
//! a timeout that it wants (as long as it is less than 30s), | ||
//! and the server has sane defaults | ||
|
||
use std::time::Duration; | ||
|
||
use tonic::{codegen::http::Request, server::NamedService, transport::Body}; | ||
use tower::{Layer, Service}; | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct DefaultTimeoutService<S> { | ||
inner: S, | ||
} | ||
|
||
impl<S> Service<Request<Body>> for DefaultTimeoutService<S> | ||
where | ||
S: Service<Request<Body>>, | ||
{ | ||
type Response = S::Response; | ||
type Error = S::Error; | ||
type Future = S::Future; | ||
|
||
fn poll_ready( | ||
&mut self, | ||
cx: &mut std::task::Context<'_>, | ||
) -> std::task::Poll<Result<(), Self::Error>> { | ||
self.inner.poll_ready(cx) | ||
} | ||
|
||
fn call(&mut self, mut req: Request<Body>) -> Self::Future { | ||
if !req.uri().path().ends_with("Blocking") { | ||
req.headers_mut() | ||
.entry("grpc-timeout") | ||
.or_insert_with(move || { | ||
let dur = Duration::from_millis(100); | ||
tonic::codegen::http::HeaderValue::from_str(&format!("{}u", dur.as_micros())) | ||
.expect("numbers are always valid ascii") | ||
}); | ||
}; | ||
|
||
self.inner.call(req) | ||
} | ||
} | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct DefaultTimeoutLayer; | ||
|
||
impl<S> Layer<S> for DefaultTimeoutLayer { | ||
type Service = DefaultTimeoutService<S>; | ||
|
||
fn layer(&self, inner: S) -> Self::Service { | ||
DefaultTimeoutService { inner } | ||
} | ||
} | ||
|
||
impl<T: NamedService> NamedService for DefaultTimeoutService<T> { | ||
const NAME: &'static str = T::NAME; | ||
} | ||
|
||
mod test { | ||
#[test] | ||
fn overrides_timeout_for_non_blocking() {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters