Move Response::unit and stream to the heap

This commit is contained in:
Martin Algesten
2021-03-24 21:01:42 +01:00
parent cfaca317c6
commit 7c6ed53df3
3 changed files with 26 additions and 8 deletions

View File

@@ -416,4 +416,12 @@ mod tests {
let _error: Box<dyn Send> = Box::new(Error::new(ErrorKind::Io, None)); let _error: Box<dyn Send> = Box::new(Error::new(ErrorKind::Io, None));
let _error: Box<dyn Sync> = Box::new(Error::new(ErrorKind::Io, None)); let _error: Box<dyn Sync> = Box::new(Error::new(ErrorKind::Io, None));
} }
#[test]
fn ensure_error_size() {
// This is platform dependent, so we can't be too strict or precise.
let size = std::mem::size_of::<Error>();
println!("Error size: {}", size);
assert!(size < 500); // 344 on Macbook M1
}
} }

View File

@@ -225,13 +225,13 @@ impl PoolKey {
/// *Internal API* /// *Internal API*
pub(crate) struct PoolReturnRead<R: Read + Sized + Into<Stream>> { pub(crate) struct PoolReturnRead<R: Read + Sized + Into<Stream>> {
// unit that contains the agent where we want to return the reader. // unit that contains the agent where we want to return the reader.
unit: Option<Unit>, unit: Option<Box<Unit>>,
// wrapped reader around the same stream // wrapped reader around the same stream
reader: Option<R>, reader: Option<R>,
} }
impl<R: Read + Sized + Into<Stream>> PoolReturnRead<R> { impl<R: Read + Sized + Into<Stream>> PoolReturnRead<R> {
pub fn new(unit: Option<Unit>, reader: R) -> Self { pub fn new(unit: Option<Box<Unit>>, reader: R) -> Self {
PoolReturnRead { PoolReturnRead {
unit, unit,
reader: Some(reader), reader: Some(reader),

View File

@@ -58,8 +58,10 @@ pub struct Response {
index: ResponseStatusIndex, index: ResponseStatusIndex,
status: u16, status: u16,
headers: Vec<Header>, headers: Vec<Header>,
unit: Option<Unit>, // Boxed to avoid taking up too much size.
stream: Stream, unit: Option<Box<Unit>>,
// Boxed to avoid taking up too much size.
stream: Box<Stream>,
/// The redirect history of this response, if any. The history starts with /// The redirect history of this response, if any. The history starts with
/// the first response received and ends with the response immediately /// the first response received and ends with the response immediately
/// previous to this one. /// previous to this one.
@@ -255,7 +257,7 @@ impl Response {
.map(|c| c.eq_ignore_ascii_case("close")) .map(|c| c.eq_ignore_ascii_case("close"))
.unwrap_or(false); .unwrap_or(false);
let is_head = (&self.unit).as_ref().map(|u| u.is_head()).unwrap_or(false); let is_head = self.unit.as_ref().map(|u| u.is_head()).unwrap_or(false);
let has_no_body = is_head let has_no_body = is_head
|| match self.status { || match self.status {
204 | 304 => true, 204 | 304 => true,
@@ -288,7 +290,7 @@ impl Response {
} }
} }
let deadline = unit.as_ref().and_then(|u| u.deadline); let deadline = unit.as_ref().and_then(|u| u.deadline);
let stream = DeadlineStream::new(stream, deadline); let stream = DeadlineStream::new(*stream, deadline);
match (use_chunked, limit_bytes) { match (use_chunked, limit_bytes) {
(true, _) => Box::new(PoolReturnRead::new(unit, ChunkDecoder::new(stream))), (true, _) => Box::new(PoolReturnRead::new(unit, ChunkDecoder::new(stream))),
@@ -482,8 +484,8 @@ impl Response {
index, index,
status, status,
headers, headers,
unit, unit: unit.map(Box::new),
stream: stream.into(), stream: Box::new(stream.into()),
history: vec![], history: vec![],
}) })
} }
@@ -955,4 +957,12 @@ mod tests {
let _response: Box<dyn Send> = Box::new(Response::new(302, "Found", "").unwrap()); let _response: Box<dyn Send> = Box::new(Response::new(302, "Found", "").unwrap());
let _response: Box<dyn Sync> = Box::new(Response::new(302, "Found", "").unwrap()); let _response: Box<dyn Sync> = Box::new(Response::new(302, "Found", "").unwrap());
} }
#[test]
fn ensure_response_size() {
// This is platform dependent, so we can't be too strict or precise.
let size = std::mem::size_of::<Response>();
println!("Response size: {}", size);
assert!(size < 400); // 200 on Macbook M1
}
} }