Skip to content

Add a way to force queued strategy #2285

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions src/client/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ where
#[derive(Clone, Debug)]
pub struct Builder {
pub(super) exec: Exec,
h1_writev: bool,
h1_writev: Option<bool>,
h1_title_case_headers: bool,
h1_read_buf_exact_size: Option<usize>,
h1_max_buf_size: Option<usize>,
Expand Down Expand Up @@ -424,7 +424,7 @@ impl Builder {
pub fn new() -> Builder {
Builder {
exec: Exec::Default,
h1_writev: true,
h1_writev: None,
h1_read_buf_exact_size: None,
h1_title_case_headers: false,
h1_max_buf_size: None,
Expand All @@ -443,7 +443,7 @@ impl Builder {
}

pub(super) fn h1_writev(&mut self, enabled: bool) -> &mut Builder {
self.h1_writev = enabled;
self.h1_writev = Some(enabled);
self
}

Expand Down Expand Up @@ -609,8 +609,12 @@ impl Builder {
let (tx, rx) = dispatch::channel();
let proto = if !opts.http2 {
let mut conn = proto::Conn::new(io);
if !opts.h1_writev {
conn.set_write_strategy_flatten();
if let Some(writev) = opts.h1_writev {
if writev {
conn.set_write_strategy_queue();
} else {
conn.set_write_strategy_flatten();
}
}
if opts.h1_title_case_headers {
conn.set_title_case_headers();
Expand Down
6 changes: 5 additions & 1 deletion src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -964,7 +964,11 @@ impl Builder {
/// but may also improve performance when an IO transport doesn't
/// support vectored writes well, such as most TLS implementations.
///
/// Default is `true`.
/// Setting this to true will force hyper to use queued strategy
/// which may eliminate unnecessary cloning on some TLS backends
///
/// Default is `auto`. In this mode hyper will try to guess which
/// mode to use
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
self.conn_builder.h1_writev(val);
self
Expand Down
4 changes: 4 additions & 0 deletions src/proto/h1/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ where
self.io.set_write_strategy_flatten();
}

pub fn set_write_strategy_queue(&mut self) {
self.io.set_write_strategy_queue();
}

pub fn set_title_case_headers(&mut self) {
self.state.title_case_headers = true;
}
Expand Down
7 changes: 7 additions & 0 deletions src/proto/h1/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ where
self.write_buf.set_strategy(WriteStrategy::Flatten);
}

pub fn set_write_strategy_queue(&mut self) {
// this should always be called only at construction time,
// so this assert is here to catch myself
debug_assert!(self.write_buf.queue.bufs_cnt() == 0);
self.write_buf.set_strategy(WriteStrategy::Queue);
}

pub fn read_buf(&self) -> &[u8] {
self.read_buf.as_ref()
}
Expand Down
20 changes: 14 additions & 6 deletions src/server/conn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ pub struct Http<E = Exec> {
exec: E,
h1_half_close: bool,
h1_keep_alive: bool,
h1_writev: bool,
h1_writev: Option<bool>,
h2_builder: proto::h2::server::Config,
mode: ConnectionMode,
max_buf_size: Option<usize>,
Expand Down Expand Up @@ -217,7 +217,7 @@ impl Http {
exec: Exec::Default,
h1_half_close: false,
h1_keep_alive: true,
h1_writev: true,
h1_writev: None,
h2_builder: Default::default(),
mode: ConnectionMode::Fallback,
max_buf_size: None,
Expand Down Expand Up @@ -274,10 +274,14 @@ impl<E> Http<E> {
/// but may also improve performance when an IO transport doesn't
/// support vectored writes well, such as most TLS implementations.
///
/// Default is `true`.
/// Setting this to true will force hyper to use queued strategy
/// which may eliminate unnecessary cloning on some TLS backends
///
/// Default is `auto`. In this mode hyper will try to guess which
/// mode to use
#[inline]
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
self.h1_writev = val;
self.h1_writev = Some(val);
self
}

Expand Down Expand Up @@ -487,8 +491,12 @@ impl<E> Http<E> {
if self.h1_half_close {
conn.set_allow_half_close();
}
if !self.h1_writev {
conn.set_write_strategy_flatten();
if let Some(writev) = self.h1_writev {
if writev {
conn.set_write_strategy_queue();
} else {
conn.set_write_strategy_flatten();
}
}
conn.set_flush_pipeline(self.pipeline_flush);
if let Some(max) = self.max_buf_size {
Expand Down
6 changes: 5 additions & 1 deletion src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,11 @@ impl<I, E> Builder<I, E> {
/// but may also improve performance when an IO transport doesn't
/// support vectored writes well, such as most TLS implementations.
///
/// Default is `true`.
/// Setting this to true will force hyper to use queued strategy
/// which may eliminate unnecessary cloning on some TLS backends
///
/// Default is `auto`. In this mode hyper will try to guess which
/// mode to use
pub fn http1_writev(mut self, val: bool) -> Self {
self.protocol.http1_writev(val);
self
Expand Down