perf(h1): reduce clock checks for date rendering when pipelined
This commit is contained in:
@@ -9,12 +9,13 @@ pub const DATE_VALUE_LENGTH: usize = 29;
|
|||||||
|
|
||||||
pub fn extend(dst: &mut Vec<u8>) {
|
pub fn extend(dst: &mut Vec<u8>) {
|
||||||
CACHED.with(|cache| {
|
CACHED.with(|cache| {
|
||||||
let mut cache = cache.borrow_mut();
|
dst.extend_from_slice(cache.borrow().buffer());
|
||||||
let now = time::get_time();
|
})
|
||||||
if now > cache.next_update {
|
}
|
||||||
cache.update(now);
|
|
||||||
}
|
pub fn update() {
|
||||||
dst.extend_from_slice(cache.buffer());
|
CACHED.with(|cache| {
|
||||||
|
cache.borrow_mut().check();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,17 +25,30 @@ struct CachedDate {
|
|||||||
next_update: time::Timespec,
|
next_update: time::Timespec,
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_local!(static CACHED: RefCell<CachedDate> = RefCell::new(CachedDate {
|
thread_local!(static CACHED: RefCell<CachedDate> = RefCell::new(CachedDate::new()));
|
||||||
bytes: [0; DATE_VALUE_LENGTH],
|
|
||||||
pos: 0,
|
|
||||||
next_update: time::Timespec::new(0, 0),
|
|
||||||
}));
|
|
||||||
|
|
||||||
impl CachedDate {
|
impl CachedDate {
|
||||||
|
fn new() -> Self {
|
||||||
|
let mut cache = CachedDate {
|
||||||
|
bytes: [0; DATE_VALUE_LENGTH],
|
||||||
|
pos: 0,
|
||||||
|
next_update: time::Timespec::new(0, 0),
|
||||||
|
};
|
||||||
|
cache.update(time::get_time());
|
||||||
|
cache
|
||||||
|
}
|
||||||
|
|
||||||
fn buffer(&self) -> &[u8] {
|
fn buffer(&self) -> &[u8] {
|
||||||
&self.bytes[..]
|
&self.bytes[..]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check(&mut self) {
|
||||||
|
let now = time::get_time();
|
||||||
|
if now > self.next_update {
|
||||||
|
self.update(now);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update(&mut self, now: time::Timespec) {
|
fn update(&mut self, now: time::Timespec) {
|
||||||
self.pos = 0;
|
self.pos = 0;
|
||||||
let _ = write!(self, "{}", time::at_utc(now).rfc822());
|
let _ = write!(self, "{}", time::at_utc(now).rfc822());
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll_inner(&mut self, should_shutdown: bool) -> Poll<(), ::Error> {
|
fn poll_inner(&mut self, should_shutdown: bool) -> Poll<(), ::Error> {
|
||||||
|
T::update_date();
|
||||||
loop {
|
loop {
|
||||||
self.poll_read()?;
|
self.poll_read()?;
|
||||||
self.poll_write()?;
|
self.poll_write()?;
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ pub(crate) trait Http1Transaction {
|
|||||||
|
|
||||||
fn should_error_on_parse_eof() -> bool;
|
fn should_error_on_parse_eof() -> bool;
|
||||||
fn should_read_first() -> bool;
|
fn should_read_first() -> bool;
|
||||||
|
|
||||||
|
fn update_date() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type ParseResult<T> = Result<Option<ParsedMessage<T>>, ::error::Parse>;
|
pub(crate) type ParseResult<T> = Result<Option<ParsedMessage<T>>, ::error::Parse>;
|
||||||
|
|||||||
@@ -182,34 +182,6 @@ where
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
fn decoder(head: &MessageHead<Self::Incoming>, method: &mut Option<Method>) -> ::Result<Decode> {
|
|
||||||
*method = Some(head.subject.0.clone());
|
|
||||||
if head.headers.contains_key(TRANSFER_ENCODING) {
|
|
||||||
// https://tools.ietf.org/html/rfc7230#section-3.3.3
|
|
||||||
// If Transfer-Encoding header is present, and 'chunked' is
|
|
||||||
// not the final encoding, and this is a Request, then it is
|
|
||||||
// mal-formed. A server should respond with 400 Bad Request.
|
|
||||||
if head.version == Version::HTTP_10 {
|
|
||||||
debug!("HTTP/1.0 cannot have Transfer-Encoding header");
|
|
||||||
Err(::Error::new_header())
|
|
||||||
} else if headers::transfer_encoding_is_chunked(&head.headers) {
|
|
||||||
Ok(Decode::Normal(Decoder::chunked()))
|
|
||||||
} else {
|
|
||||||
debug!("request with transfer-encoding header, but not chunked, bad request");
|
|
||||||
Err(::Error::new_header())
|
|
||||||
}
|
|
||||||
} else if let Some(len) = headers::content_length_parse(&head.headers) {
|
|
||||||
Ok(Decode::Normal(Decoder::length(len)))
|
|
||||||
} else if head.headers.contains_key(CONTENT_LENGTH) {
|
|
||||||
debug!("illegal Content-Length header");
|
|
||||||
Err(::Error::new_header())
|
|
||||||
} else {
|
|
||||||
Ok(Decode::Normal(Decoder::length(0)))
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
fn encode(mut msg: Encode<Self::Outgoing>, dst: &mut Vec<u8>) -> ::Result<Encoder> {
|
fn encode(mut msg: Encode<Self::Outgoing>, dst: &mut Vec<u8>) -> ::Result<Encoder> {
|
||||||
trace!("Server::encode body={:?}, method={:?}", msg.body, msg.req_method);
|
trace!("Server::encode body={:?}, method={:?}", msg.body, msg.req_method);
|
||||||
debug_assert!(!msg.title_case_headers, "no server config for title case headers");
|
debug_assert!(!msg.title_case_headers, "no server config for title case headers");
|
||||||
@@ -464,6 +436,10 @@ where
|
|||||||
fn should_read_first() -> bool {
|
fn should_read_first() -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_date() {
|
||||||
|
date::update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server<()> {
|
impl Server<()> {
|
||||||
|
|||||||
Reference in New Issue
Block a user