feat(lib): Setting http1_writev(true) will now force writev queue usage
Previously, calling `http1_writev(true)` would just keep the default behavior, which was to auto detect if writev was optimal. Now, the auto-detection is still default, but explicitly calling `http1_writev(true)` will skip the auto-detection, and always use writev queue strategy. Closes #2282
This commit is contained in:
@@ -75,7 +75,7 @@ where
|
|||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
pub(super) exec: Exec,
|
pub(super) exec: Exec,
|
||||||
h1_writev: bool,
|
h1_writev: Option<bool>,
|
||||||
h1_title_case_headers: bool,
|
h1_title_case_headers: bool,
|
||||||
h1_read_buf_exact_size: Option<usize>,
|
h1_read_buf_exact_size: Option<usize>,
|
||||||
h1_max_buf_size: Option<usize>,
|
h1_max_buf_size: Option<usize>,
|
||||||
@@ -424,7 +424,7 @@ impl Builder {
|
|||||||
pub fn new() -> Builder {
|
pub fn new() -> Builder {
|
||||||
Builder {
|
Builder {
|
||||||
exec: Exec::Default,
|
exec: Exec::Default,
|
||||||
h1_writev: true,
|
h1_writev: None,
|
||||||
h1_read_buf_exact_size: None,
|
h1_read_buf_exact_size: None,
|
||||||
h1_title_case_headers: false,
|
h1_title_case_headers: false,
|
||||||
h1_max_buf_size: None,
|
h1_max_buf_size: None,
|
||||||
@@ -443,7 +443,7 @@ impl Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn h1_writev(&mut self, enabled: bool) -> &mut Builder {
|
pub(super) fn h1_writev(&mut self, enabled: bool) -> &mut Builder {
|
||||||
self.h1_writev = enabled;
|
self.h1_writev = Some(enabled);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,8 +609,12 @@ impl Builder {
|
|||||||
let (tx, rx) = dispatch::channel();
|
let (tx, rx) = dispatch::channel();
|
||||||
let proto = if !opts.http2 {
|
let proto = if !opts.http2 {
|
||||||
let mut conn = proto::Conn::new(io);
|
let mut conn = proto::Conn::new(io);
|
||||||
if !opts.h1_writev {
|
if let Some(writev) = opts.h1_writev {
|
||||||
conn.set_write_strategy_flatten();
|
if writev {
|
||||||
|
conn.set_write_strategy_queue();
|
||||||
|
} else {
|
||||||
|
conn.set_write_strategy_flatten();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if opts.h1_title_case_headers {
|
if opts.h1_title_case_headers {
|
||||||
conn.set_title_case_headers();
|
conn.set_title_case_headers();
|
||||||
|
|||||||
@@ -964,7 +964,11 @@ impl Builder {
|
|||||||
/// but may also improve performance when an IO transport doesn't
|
/// but may also improve performance when an IO transport doesn't
|
||||||
/// support vectored writes well, such as most TLS implementations.
|
/// 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 {
|
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
|
||||||
self.conn_builder.h1_writev(val);
|
self.conn_builder.h1_writev(val);
|
||||||
self
|
self
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ where
|
|||||||
self.io.set_write_strategy_flatten();
|
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) {
|
pub fn set_title_case_headers(&mut self) {
|
||||||
self.state.title_case_headers = true;
|
self.state.title_case_headers = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,13 @@ where
|
|||||||
self.write_buf.set_strategy(WriteStrategy::Flatten);
|
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] {
|
pub fn read_buf(&self) -> &[u8] {
|
||||||
self.read_buf.as_ref()
|
self.read_buf.as_ref()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ pub struct Http<E = Exec> {
|
|||||||
exec: E,
|
exec: E,
|
||||||
h1_half_close: bool,
|
h1_half_close: bool,
|
||||||
h1_keep_alive: bool,
|
h1_keep_alive: bool,
|
||||||
h1_writev: bool,
|
h1_writev: Option<bool>,
|
||||||
h2_builder: proto::h2::server::Config,
|
h2_builder: proto::h2::server::Config,
|
||||||
mode: ConnectionMode,
|
mode: ConnectionMode,
|
||||||
max_buf_size: Option<usize>,
|
max_buf_size: Option<usize>,
|
||||||
@@ -217,7 +217,7 @@ impl Http {
|
|||||||
exec: Exec::Default,
|
exec: Exec::Default,
|
||||||
h1_half_close: false,
|
h1_half_close: false,
|
||||||
h1_keep_alive: true,
|
h1_keep_alive: true,
|
||||||
h1_writev: true,
|
h1_writev: None,
|
||||||
h2_builder: Default::default(),
|
h2_builder: Default::default(),
|
||||||
mode: ConnectionMode::Fallback,
|
mode: ConnectionMode::Fallback,
|
||||||
max_buf_size: None,
|
max_buf_size: None,
|
||||||
@@ -274,10 +274,14 @@ impl<E> Http<E> {
|
|||||||
/// but may also improve performance when an IO transport doesn't
|
/// but may also improve performance when an IO transport doesn't
|
||||||
/// support vectored writes well, such as most TLS implementations.
|
/// 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]
|
#[inline]
|
||||||
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
|
pub fn http1_writev(&mut self, val: bool) -> &mut Self {
|
||||||
self.h1_writev = val;
|
self.h1_writev = Some(val);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -487,8 +491,12 @@ impl<E> Http<E> {
|
|||||||
if self.h1_half_close {
|
if self.h1_half_close {
|
||||||
conn.set_allow_half_close();
|
conn.set_allow_half_close();
|
||||||
}
|
}
|
||||||
if !self.h1_writev {
|
if let Some(writev) = self.h1_writev {
|
||||||
conn.set_write_strategy_flatten();
|
if writev {
|
||||||
|
conn.set_write_strategy_queue();
|
||||||
|
} else {
|
||||||
|
conn.set_write_strategy_flatten();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
conn.set_flush_pipeline(self.pipeline_flush);
|
conn.set_flush_pipeline(self.pipeline_flush);
|
||||||
if let Some(max) = self.max_buf_size {
|
if let Some(max) = self.max_buf_size {
|
||||||
|
|||||||
@@ -286,7 +286,11 @@ impl<I, E> Builder<I, E> {
|
|||||||
/// but may also improve performance when an IO transport doesn't
|
/// but may also improve performance when an IO transport doesn't
|
||||||
/// support vectored writes well, such as most TLS implementations.
|
/// 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 {
|
pub fn http1_writev(mut self, val: bool) -> Self {
|
||||||
self.protocol.http1_writev(val);
|
self.protocol.http1_writev(val);
|
||||||
self
|
self
|
||||||
|
|||||||
Reference in New Issue
Block a user