Merge pull request #860 from hyperium/idle-timeout

Idle timeouts for Server and Client
This commit is contained in:
Sean McArthur
2016-07-14 20:36:24 -07:00
committed by GitHub
2 changed files with 28 additions and 6 deletions

View File

@@ -145,6 +145,8 @@ pub struct Config<C> {
connect_timeout: Duration, connect_timeout: Duration,
connector: C, connector: C,
keep_alive: bool, keep_alive: bool,
keep_alive_timeout: Option<Duration>,
//TODO: make use of max_idle config
max_idle: usize, max_idle: usize,
max_sockets: usize, max_sockets: usize,
} }
@@ -157,6 +159,7 @@ impl<C> Config<C> where C: Connect + Send + 'static {
connect_timeout: self.connect_timeout, connect_timeout: self.connect_timeout,
connector: val, connector: val,
keep_alive: self.keep_alive, keep_alive: self.keep_alive,
keep_alive_timeout: Some(Duration::from_secs(60 * 2)),
max_idle: self.max_idle, max_idle: self.max_idle,
max_sockets: self.max_sockets, max_sockets: self.max_sockets,
} }
@@ -171,6 +174,17 @@ impl<C> Config<C> where C: Connect + Send + 'static {
self self
} }
/// Set an optional timeout for idle sockets being kept-alive.
///
/// Pass `None` to disable timeout.
///
/// Default is 2 minutes.
#[inline]
pub fn keep_alive_timeout(mut self, val: Option<Duration>) -> Config<C> {
self.keep_alive_timeout = val;
self
}
/// Set the max table size allocated for holding on to live sockets. /// Set the max table size allocated for holding on to live sockets.
/// ///
/// Default is 1024. /// Default is 1024.
@@ -202,6 +216,7 @@ impl Default for Config<DefaultConnector> {
connect_timeout: Duration::from_secs(10), connect_timeout: Duration::from_secs(10),
connector: DefaultConnector::default(), connector: DefaultConnector::default(),
keep_alive: true, keep_alive: true,
keep_alive_timeout: Some(Duration::from_secs(60 * 2)),
max_idle: 5, max_idle: 5,
max_sockets: 1024, max_sockets: 1024,
} }

View File

@@ -40,7 +40,7 @@ impl<A: Accept, H: HandlerFactory<A::Output>> fmt::Debug for ServerLoop<A, H> {
pub struct Server<T: Accept> { pub struct Server<T: Accept> {
listener: T, listener: T,
keep_alive: bool, keep_alive: bool,
idle_timeout: Duration, idle_timeout: Option<Duration>,
max_sockets: usize, max_sockets: usize,
} }
@@ -51,7 +51,7 @@ impl<T> Server<T> where T: Accept, T::Output: Transport {
Server { Server {
listener: listener, listener: listener,
keep_alive: true, keep_alive: true,
idle_timeout: Duration::from_secs(10), idle_timeout: Some(Duration::from_secs(10)),
max_sockets: 4096, max_sockets: 4096,
} }
} }
@@ -67,7 +67,7 @@ impl<T> Server<T> where T: Accept, T::Output: Transport {
/// Sets how long an idle connection will be kept before closing. /// Sets how long an idle connection will be kept before closing.
/// ///
/// Default is 10 seconds. /// Default is 10 seconds.
pub fn idle_timeout(mut self, val: Duration) -> Server<T> { pub fn idle_timeout(mut self, val: Option<Duration>) -> Server<T> {
self.idle_timeout = val; self.idle_timeout = val;
self self
} }
@@ -117,6 +117,7 @@ impl<A: Accept> Server<A> where A::Output: Transport {
config.slab_capacity(self.max_sockets); config.slab_capacity(self.max_sockets);
config.mio().notify_capacity(self.max_sockets); config.mio().notify_capacity(self.max_sockets);
let keep_alive = self.keep_alive; let keep_alive = self.keep_alive;
let idle_timeout = self.idle_timeout;
let mut loop_ = rotor::Loop::new(&config).unwrap(); let mut loop_ = rotor::Loop::new(&config).unwrap();
let mut notifier = None; let mut notifier = None;
{ {
@@ -135,8 +136,9 @@ impl<A: Accept> Server<A> where A::Output: Transport {
}; };
let server = ServerLoop { let server = ServerLoop {
inner: Some((loop_, Context { inner: Some((loop_, Context {
factory: factory,
idle_timeout: idle_timeout,
keep_alive: keep_alive, keep_alive: keep_alive,
factory: factory
})) }))
}; };
Ok((listening, server)) Ok((listening, server))
@@ -162,8 +164,9 @@ impl<A: Accept, H: HandlerFactory<A::Output>> Drop for ServerLoop<A, H> {
} }
struct Context<F> { struct Context<F> {
keep_alive: bool,
factory: F, factory: F,
idle_timeout: Option<Duration>,
keep_alive: bool,
} }
impl<F: HandlerFactory<T>, T: Transport> http::MessageHandlerFactory<(), T> for Context<F> { impl<F: HandlerFactory<T>, T: Transport> http::MessageHandlerFactory<(), T> for Context<F> {
@@ -174,7 +177,11 @@ impl<F: HandlerFactory<T>, T: Transport> http::MessageHandlerFactory<(), T> for
} }
fn keep_alive_interest(&self) -> Next { fn keep_alive_interest(&self) -> Next {
Next::read() if let Some(dur) = self.idle_timeout {
Next::read().timeout(dur)
} else {
Next::read()
}
} }
} }