0

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.

1
  • Noted, I have found that it is feasible to fill the data with a new temporary buffer and then fill the data into the buf when it is truly ready to return Poll::Ready. But why? Commented May 11 at 6:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.