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())); | ||||||
|  |  | ||||||
|  | impl CachedDate { | ||||||
|  |     fn new() -> Self { | ||||||
|  |         let mut cache = CachedDate { | ||||||
|             bytes: [0; DATE_VALUE_LENGTH], |             bytes: [0; DATE_VALUE_LENGTH], | ||||||
|             pos: 0, |             pos: 0, | ||||||
|             next_update: time::Timespec::new(0, 0), |             next_update: time::Timespec::new(0, 0), | ||||||
| })); |         }; | ||||||
|  |         cache.update(time::get_time()); | ||||||
|  |         cache | ||||||
|  |     } | ||||||
|  |  | ||||||
| impl CachedDate { |  | ||||||
|     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