From 4dfe0db0f4e54337cd6727cd29e1ad44aca50178 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Fri, 23 Jun 2017 18:52:32 -0700 Subject: [PATCH] perf(server): dont record Idle time when not needed --- src/client/pool.rs | 29 ++++++++++++++++++++--------- src/http/conn.rs | 12 ++++-------- src/http/io.rs | 8 +++++++- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/src/client/pool.rs b/src/client/pool.rs index 042ac03e..c8665792 100644 --- a/src/client/pool.rs +++ b/src/client/pool.rs @@ -80,7 +80,7 @@ impl Pool { entry: Entry { value: value, is_reused: false, - status: Rc::new(Cell::new(KA::Busy)), + status: Rc::new(Cell::new(TimedKA::Busy)), }, key: key, pool: self.clone(), @@ -94,7 +94,7 @@ impl Pool { fn reuse(&self, key: Rc, mut entry: Entry) -> Pooled { trace!("Pool::reuse {:?}", key); entry.is_reused = true; - entry.status.set(KA::Busy); + entry.status.set(TimedKA::Busy); Pooled { entry: entry, key: key, @@ -141,17 +141,17 @@ impl DerefMut for Pooled { impl KeepAlive for Pooled { fn busy(&mut self) { - self.entry.status.set(KA::Busy); + self.entry.status.set(TimedKA::Busy); } fn disable(&mut self) { - self.entry.status.set(KA::Disabled); + self.entry.status.set(TimedKA::Disabled); } fn idle(&mut self) { let previous = self.status(); - self.entry.status.set(KA::Idle(Instant::now())); - if let KA::Idle(..) = previous { + self.entry.status.set(TimedKA::Idle(Instant::now())); + if let KA::Idle = previous { trace!("Pooled::idle already idle"); return; } @@ -162,7 +162,11 @@ impl KeepAlive for Pooled { } fn status(&self) -> KA { - self.entry.status.get() + match self.entry.status.get() { + TimedKA::Idle(_) => KA::Idle, + TimedKA::Busy => KA::Busy, + TimedKA::Disabled => KA::Disabled, + } } } @@ -187,7 +191,14 @@ impl BitAndAssign for Pooled { struct Entry { value: T, is_reused: bool, - status: Rc>, + status: Rc>, +} + +#[derive(Clone, Copy, Debug)] +enum TimedKA { + Idle(Instant), + Busy, + Disabled, } pub struct Checkout { @@ -224,7 +235,7 @@ impl Future for Checkout { trace!("Checkout::poll key found {:?}", key); while let Some(entry) = list.pop() { match entry.status.get() { - KA::Idle(idle_at) if !expiration.expires(idle_at) => { + TimedKA::Idle(idle_at) if !expiration.expires(idle_at) => { trace!("Checkout::poll found idle client for {:?}", key); should_remove = list.is_empty(); return Some(entry); diff --git a/src/http/conn.rs b/src/http/conn.rs index bb2cee0b..890740db 100644 --- a/src/http/conn.rs +++ b/src/http/conn.rs @@ -1,7 +1,6 @@ use std::fmt; use std::io::{self, Write}; use std::marker::PhantomData; -use std::time::Instant; use futures::{Poll, Async, AsyncSink, Stream, Sink, StartSend}; use futures::task::Task; @@ -228,10 +227,7 @@ where I: AsyncRead + AsyncWrite, let wants_keep_alive = head.should_keep_alive(); self.state.keep_alive &= wants_keep_alive; - let mut buf = Vec::new(); - let encoder = T::encode(head, &mut buf); - //TODO: handle when there isn't enough room to buffer the head - assert!(self.io.buffer(buf) > 0); + let encoder = T::encode(head, self.io.write_buf_mut()); self.state.writing = if body { Writing::Body(encoder, None) } else { @@ -534,7 +530,7 @@ pub trait KeepAlive: fmt::Debug + ::std::ops::BitAndAssign { #[derive(Clone, Copy, Debug)] pub enum KA { - Idle(Instant), + Idle, Busy, Disabled, } @@ -547,7 +543,7 @@ impl Default for KA { impl KeepAlive for KA { fn idle(&mut self) { - *self = KA::Idle(Instant::now()); + *self = KA::Idle; } fn busy(&mut self) { @@ -595,7 +591,7 @@ impl State { } fn is_idle(&self) -> bool { - if let KA::Idle(..) = self.keep_alive.status() { + if let KA::Idle = self.keep_alive.status() { true } else { false diff --git a/src/http/io.rs b/src/http/io.rs index 1d942868..ab26a013 100644 --- a/src/http/io.rs +++ b/src/http/io.rs @@ -42,6 +42,12 @@ impl Buffered { self.read_buf.as_ref() } + pub fn write_buf_mut(&mut self) -> &mut Vec { + self.write_buf.maybe_reset(); + self.write_buf.maybe_reserve(0); + &mut self.write_buf.0.bytes + } + pub fn consume_leading_lines(&mut self) { if !self.read_buf.is_empty() { let mut i = 0; @@ -133,7 +139,7 @@ impl Write for Buffered { } else { loop { let n = try!(self.write_buf.write_into(&mut self.io)); - debug!("flushed {} bytes", n); + trace!("flushed {} bytes", n); if self.write_buf.remaining() == 0 { break; }