I have a few public types that implement AsyncRead/Write, but I haven't looked at vectored IO yet. I read sometimes that it's bad that people forget to implement these methods because default impls are provided.
Unfortunately, the docs on futures lib don't tell you that and even less when it's appropriate to implement them.
As an example. I put AsyncRead/AsyncWrite on top of websockets.
I buffer up to one websocket message. In
poll_read, I try to get a message out of the underlying stream if I don't have one. Then I try to copy as much of it as I can into the buffer I got. I keep track of how far we read into the message in case it didn't fit entirely, then next time we will fit the rest.
However if the buffer is bigger than the message, currently I just don't fill it entirely (same as
futures::IntoAsyncRead). So the first question is, should I poll the stream for the next message, knowing that it might just return pending, and that we cannot return pending here (as we already filled part of the buffer), so it will wake up the task even though we didn't return pending in
Is such a spurious wakup a problem? Maybe just call with a dummy waker when we already have data to return?
Secondly then should I implement
poll_read_vectored for this? I suppose I could fill several buffers, instead of just filling the first one like the default impl does, but that means either:
- only do that when the ws message is to big to fit in the first buffer
- solving the
poll_readquestion above so that we can fill the buffers with data from several websocket messages? If it is fine to have spurious wakeups, why does the default impl not call
poll_readseveral times in order to fill up all the buffers until
poll_readreturns pending? It could also do something like the dummy waker.
poll_write_vector, the implementation itself is simpler. The websocket api just wants a
Vec<u8> for the websocket message, so I could just allocate one big enough for the total of all vectors passed in and copy all the data in there.
So is it appropriate for such a layer on websockets to implement
poll_write_vectored even though the actual networking layer doesn't really do vectored IO and I will copy all buffers into one