mirror of
https://github.com/ntex-rs/ntex.git
synced 2025-04-03 21:07:39 +03:00
Refactor io write task (#167)
This commit is contained in:
parent
c794439139
commit
38614715ca
18 changed files with 418 additions and 411 deletions
|
@ -1,5 +1,9 @@
|
|||
# Changes
|
||||
|
||||
## [0.2.2] - 2023-01-26
|
||||
|
||||
* Update io api usage
|
||||
|
||||
## [0.2.0] - 2023-01-04
|
||||
|
||||
* Release
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "ntex-tokio"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
authors = ["ntex contributors <team@ntex.rs>"]
|
||||
description = "tokio intergration for ntex framework"
|
||||
keywords = ["network", "framework", "async", "futures"]
|
||||
|
@ -17,7 +17,7 @@ path = "src/lib.rs"
|
|||
|
||||
[dependencies]
|
||||
ntex-bytes = "0.1.19"
|
||||
ntex-io = "0.2.1"
|
||||
ntex-io = "0.2.4"
|
||||
ntex-util = "0.2.0"
|
||||
log = "0.4"
|
||||
pin-project-lite = "0.2"
|
||||
|
|
|
@ -144,10 +144,17 @@ impl Future for WriteTask {
|
|||
}
|
||||
}
|
||||
|
||||
// flush framed instance
|
||||
match flush_io(&mut *this.io.borrow_mut(), &this.state, cx) {
|
||||
Poll::Pending | Poll::Ready(true) => Poll::Pending,
|
||||
Poll::Ready(false) => Poll::Ready(()),
|
||||
// flush io stream
|
||||
match ready!(this.state.with_buf(|buf| flush_io(
|
||||
&mut *this.io.borrow_mut(),
|
||||
buf,
|
||||
cx
|
||||
))) {
|
||||
Ok(()) => Poll::Pending,
|
||||
Err(e) => {
|
||||
this.state.close(Some(e));
|
||||
Poll::Ready(())
|
||||
}
|
||||
}
|
||||
}
|
||||
Poll::Ready(WriteStatus::Timeout(time)) => {
|
||||
|
@ -194,19 +201,21 @@ impl Future for WriteTask {
|
|||
match st {
|
||||
Shutdown::None => {
|
||||
// flush write buffer
|
||||
match flush_io(&mut *this.io.borrow_mut(), &this.state, cx) {
|
||||
Poll::Ready(true) => {
|
||||
let mut io = this.io.borrow_mut();
|
||||
match this.state.with_buf(|buf| flush_io(&mut *io, buf, cx)) {
|
||||
Poll::Ready(Ok(())) => {
|
||||
*st = Shutdown::Flushed;
|
||||
continue;
|
||||
}
|
||||
Poll::Ready(false) => {
|
||||
Poll::Ready(Err(err)) => {
|
||||
log::trace!(
|
||||
"write task is closed with err during flush"
|
||||
"write task is closed with err during flush, {:?}",
|
||||
err
|
||||
);
|
||||
this.state.close(None);
|
||||
this.state.close(Some(err));
|
||||
return Poll::Ready(());
|
||||
}
|
||||
_ => (),
|
||||
Poll::Pending => (),
|
||||
}
|
||||
}
|
||||
Shutdown::Flushed => {
|
||||
|
@ -272,80 +281,64 @@ impl Future for WriteTask {
|
|||
/// Flush write buffer to underlying I/O stream.
|
||||
pub(super) fn flush_io<T: AsyncRead + AsyncWrite + Unpin>(
|
||||
io: &mut T,
|
||||
state: &WriteContext,
|
||||
buf: &mut Option<BytesVec>,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<bool> {
|
||||
let mut buf = if let Some(buf) = state.get_write_buf() {
|
||||
buf
|
||||
} else {
|
||||
return Poll::Ready(true);
|
||||
};
|
||||
let len = buf.len();
|
||||
let pool = state.memory_pool();
|
||||
) -> Poll<io::Result<()>> {
|
||||
if let Some(buf) = buf {
|
||||
let len = buf.len();
|
||||
|
||||
if len != 0 {
|
||||
// log::trace!("flushing framed transport: {:?}", buf.len());
|
||||
if len != 0 {
|
||||
// log::trace!("flushing framed transport: {:?}", buf.len());
|
||||
|
||||
let mut written = 0;
|
||||
while written < len {
|
||||
match Pin::new(&mut *io).poll_write(cx, &buf[written..]) {
|
||||
Poll::Pending => break,
|
||||
Poll::Ready(Ok(n)) => {
|
||||
if n == 0 {
|
||||
log::trace!("Disconnected during flush, written {}", written);
|
||||
pool.release_write_buf(buf);
|
||||
state.close(Some(io::Error::new(
|
||||
io::ErrorKind::WriteZero,
|
||||
"failed to write frame to transport",
|
||||
)));
|
||||
return Poll::Ready(false);
|
||||
} else {
|
||||
written += n
|
||||
let mut written = 0;
|
||||
let result = loop {
|
||||
break match Pin::new(&mut *io).poll_write(cx, &buf[written..]) {
|
||||
Poll::Ready(Ok(n)) => {
|
||||
if n == 0 {
|
||||
log::trace!("Disconnected during flush, written {}", written);
|
||||
Poll::Ready(Err(io::Error::new(
|
||||
io::ErrorKind::WriteZero,
|
||||
"failed to write frame to transport",
|
||||
)))
|
||||
} else {
|
||||
written += n;
|
||||
if written == len {
|
||||
buf.clear();
|
||||
Poll::Ready(Ok(()))
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
Poll::Pending => {
|
||||
// remove written data
|
||||
buf.advance(written);
|
||||
Poll::Pending
|
||||
}
|
||||
Poll::Ready(Err(e)) => {
|
||||
log::trace!("Error during flush: {}", e);
|
||||
Poll::Ready(Err(e))
|
||||
}
|
||||
};
|
||||
};
|
||||
// log::trace!("flushed {} bytes", written);
|
||||
|
||||
// flush
|
||||
return if written > 0 {
|
||||
match Pin::new(&mut *io).poll_flush(cx) {
|
||||
Poll::Ready(Ok(_)) => result,
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(Err(e)) => {
|
||||
log::trace!("error during flush: {}", e);
|
||||
Poll::Ready(Err(e))
|
||||
}
|
||||
}
|
||||
Poll::Ready(Err(e)) => {
|
||||
log::trace!("Error during flush: {}", e);
|
||||
pool.release_write_buf(buf);
|
||||
state.close(Some(e));
|
||||
return Poll::Ready(false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
result
|
||||
};
|
||||
}
|
||||
// log::trace!("flushed {} bytes", written);
|
||||
|
||||
// remove written data
|
||||
let result = if written == len {
|
||||
buf.clear();
|
||||
if let Err(e) = state.release_write_buf(buf) {
|
||||
state.close(Some(e));
|
||||
return Poll::Ready(false);
|
||||
}
|
||||
Poll::Ready(true)
|
||||
} else {
|
||||
buf.advance(written);
|
||||
if let Err(e) = state.release_write_buf(buf) {
|
||||
state.close(Some(e));
|
||||
return Poll::Ready(false);
|
||||
}
|
||||
Poll::Pending
|
||||
};
|
||||
|
||||
// flush
|
||||
match Pin::new(&mut *io).poll_flush(cx) {
|
||||
Poll::Ready(Ok(_)) => result,
|
||||
Poll::Pending => Poll::Pending,
|
||||
Poll::Ready(Err(e)) => {
|
||||
log::trace!("error during flush: {}", e);
|
||||
state.close(Some(e));
|
||||
Poll::Ready(false)
|
||||
}
|
||||
}
|
||||
} else if let Err(e) = state.release_write_buf(buf) {
|
||||
state.close(Some(e));
|
||||
Poll::Ready(false)
|
||||
} else {
|
||||
Poll::Ready(true)
|
||||
}
|
||||
Poll::Ready(Ok(()))
|
||||
}
|
||||
|
||||
pub struct TokioIoBoxed(IoBoxed);
|
||||
|
@ -546,10 +539,17 @@ mod unixstream {
|
|||
}
|
||||
}
|
||||
|
||||
// flush framed instance
|
||||
match flush_io(&mut *this.io.borrow_mut(), &this.state, cx) {
|
||||
Poll::Pending | Poll::Ready(true) => Poll::Pending,
|
||||
Poll::Ready(false) => Poll::Ready(()),
|
||||
// flush io stream
|
||||
match ready!(this.state.with_buf(|buf| flush_io(
|
||||
&mut *this.io.borrow_mut(),
|
||||
buf,
|
||||
cx
|
||||
))) {
|
||||
Ok(()) => Poll::Pending,
|
||||
Err(e) => {
|
||||
this.state.close(Some(e));
|
||||
Poll::Ready(())
|
||||
}
|
||||
}
|
||||
}
|
||||
Poll::Ready(WriteStatus::Timeout(time)) => {
|
||||
|
@ -587,20 +587,22 @@ mod unixstream {
|
|||
match st {
|
||||
Shutdown::None => {
|
||||
// flush write buffer
|
||||
match flush_io(&mut *this.io.borrow_mut(), &this.state, cx)
|
||||
let mut io = this.io.borrow_mut();
|
||||
match this.state.with_buf(|buf| flush_io(&mut *io, buf, cx))
|
||||
{
|
||||
Poll::Ready(true) => {
|
||||
Poll::Ready(Ok(())) => {
|
||||
*st = Shutdown::Flushed;
|
||||
continue;
|
||||
}
|
||||
Poll::Ready(false) => {
|
||||
Poll::Ready(Err(err)) => {
|
||||
log::trace!(
|
||||
"write task is closed with err during flush"
|
||||
"write task is closed with err during flush, {:?}",
|
||||
err
|
||||
);
|
||||
this.state.close(None);
|
||||
this.state.close(Some(err));
|
||||
return Poll::Ready(());
|
||||
}
|
||||
_ => (),
|
||||
Poll::Pending => (),
|
||||
}
|
||||
}
|
||||
Shutdown::Flushed => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue