I am wrapping the AsyncRead by the function of Bandwidth Controling, it will read the bytes from buf firstly and try to acquire the tokens from upstream_control buckets. We assume the poll_read is Ready if it has acquired the enough tokens.
Once it need tokens more than upstream_control buckets can support, it will caused Poll::Pending, which is as we wish. However, when it acquire the tokens, the connection closed for no reason, not the client close the connection. If the request can obtain sufficient tokens at once, there will be no problem, that is, there is no need for Poll::Pending.
I am confused about it, hoping somebody could help me.
the reply of curl is:
* upload completely sent off: 18 bytes
* Empty reply from server
* shutting down connection #0
curl: (52) Empty reply from server
the Rust code is:
impl<T> AsyncRead for BandwidthControlStream<T>
where
T: AsyncStream,
{
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<io::Result<()>> {
let this = self.project();
if !*this.has_acquire_upstream {
ready!(this.inner.poll_read(cx, buf))?;
*this.has_acquire_upstream = true;
}
loop {
if let Some(acquire) = this.upstream_acquire {
match Pin::new(acquire).poll(cx){
Poll::Ready(_) => {
*this.upstream_acquire = None;
*this.has_acquire_upstream = false;
return Poll::Ready(Ok(()));
},
Poll::Pending => {
counter!(*METRIC_BLOCK_BAND_UP).increment(1);
return Poll::Pending;
},
}
} else {
let size = buf.filled().len();
if size <= 0 {
*this.has_acquire_upstream = false;
return Poll::Ready(Ok(()));
}
*this.upstream_acquire =
Some(Box::pin(this.upstream_control.clone().acquire_owned(size)));
continue;
}
}
}
}
The Connection closed for no reason if need Pending for more tokens.
bufwhen it is truly ready to return Poll::Ready. But why?