perf(server): dont record Idle time when not needed
This commit is contained in:
@@ -80,7 +80,7 @@ impl<T: Clone> Pool<T> {
|
||||
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<T: Clone> Pool<T> {
|
||||
fn reuse(&self, key: Rc<String>, mut entry: Entry<T>) -> Pooled<T> {
|
||||
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<T> DerefMut for Pooled<T> {
|
||||
|
||||
impl<T: Clone> KeepAlive for Pooled<T> {
|
||||
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<T: Clone> KeepAlive for Pooled<T> {
|
||||
}
|
||||
|
||||
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<T: Clone> BitAndAssign<bool> for Pooled<T> {
|
||||
struct Entry<T> {
|
||||
value: T,
|
||||
is_reused: bool,
|
||||
status: Rc<Cell<KA>>,
|
||||
status: Rc<Cell<TimedKA>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum TimedKA {
|
||||
Idle(Instant),
|
||||
Busy,
|
||||
Disabled,
|
||||
}
|
||||
|
||||
pub struct Checkout<T> {
|
||||
@@ -224,7 +235,7 @@ impl<T: Clone> Future for Checkout<T> {
|
||||
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);
|
||||
|
||||
@@ -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<bool> {
|
||||
|
||||
#[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<B, K: KeepAlive> State<B, K> {
|
||||
}
|
||||
|
||||
fn is_idle(&self) -> bool {
|
||||
if let KA::Idle(..) = self.keep_alive.status() {
|
||||
if let KA::Idle = self.keep_alive.status() {
|
||||
true
|
||||
} else {
|
||||
false
|
||||
|
||||
@@ -42,6 +42,12 @@ impl<T: AsyncRead + AsyncWrite> Buffered<T> {
|
||||
self.read_buf.as_ref()
|
||||
}
|
||||
|
||||
pub fn write_buf_mut(&mut self) -> &mut Vec<u8> {
|
||||
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<T: Write> Write for Buffered<T> {
|
||||
} 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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user