perf(server): try to read from socket at keep-alive
In most situations, this should reduce the number of task wake ups by 1 per request, which can help if reading the request was small.
This commit is contained in:
		| @@ -228,6 +228,16 @@ where I: AsyncRead + AsyncWrite, | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if !self.io.is_read_blocked() { |         if !self.io.is_read_blocked() { | ||||||
|  |             if self.io.read_buf().is_empty() { | ||||||
|  |                 match self.io.read_from_io() { | ||||||
|  |                     Ok(Async::Ready(_)) => (), | ||||||
|  |                     Ok(Async::NotReady) => return, | ||||||
|  |                     Err(e) => { | ||||||
|  |                         trace!("maybe_notify read_from_io error: {}", e); | ||||||
|  |                         self.state.close(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             if let Some(ref task) = self.state.read_task { |             if let Some(ref task) = self.state.read_task { | ||||||
|                 task.notify(); |                 task.notify(); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -92,9 +92,13 @@ impl<T: AsyncRead + AsyncWrite> Buffered<T> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     fn read_from_io(&mut self) -> Poll<usize, io::Error> { |     pub fn read_from_io(&mut self) -> Poll<usize, io::Error> { | ||||||
|         use bytes::BufMut; |         use bytes::BufMut; | ||||||
|         // TODO: Investigate if we still need these unsafe blocks |         self.read_blocked = false; | ||||||
|  |         //TODO: use io.read_buf(), so we don't have to zero memory | ||||||
|  |         //Reason this doesn't use it yet is because benchmarks show the | ||||||
|  |         //slightest **decrease** in performance. Switching should be done | ||||||
|  |         //when it doesn't cost anything. | ||||||
|         if self.read_buf.remaining_mut() < INIT_BUFFER_SIZE { |         if self.read_buf.remaining_mut() < INIT_BUFFER_SIZE { | ||||||
|             self.read_buf.reserve(INIT_BUFFER_SIZE); |             self.read_buf.reserve(INIT_BUFFER_SIZE); | ||||||
|             unsafe { // Zero out unused memory |             unsafe { // Zero out unused memory | ||||||
| @@ -103,13 +107,11 @@ impl<T: AsyncRead + AsyncWrite> Buffered<T> { | |||||||
|                 ptr::write_bytes(buf.as_mut_ptr(), 0, len); |                 ptr::write_bytes(buf.as_mut_ptr(), 0, len); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         self.read_blocked = false; |         unsafe { | ||||||
|         unsafe { // Can we use AsyncRead::read_buf instead? |  | ||||||
|             let n = match self.io.read(self.read_buf.bytes_mut()) { |             let n = match self.io.read(self.read_buf.bytes_mut()) { | ||||||
|                 Ok(n) => n, |                 Ok(n) => n, | ||||||
|                 Err(e) => { |                 Err(e) => { | ||||||
|                     if e.kind() == io::ErrorKind::WouldBlock { |                     if e.kind() == io::ErrorKind::WouldBlock { | ||||||
|                         // TODO: Push this out, ideally, into http::Conn. |  | ||||||
|                         self.read_blocked = true; |                         self.read_blocked = true; | ||||||
|                         return Ok(Async::NotReady); |                         return Ok(Async::NotReady); | ||||||
|                     } |                     } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user