-
Notifications
You must be signed in to change notification settings - Fork 6
Description
We have the following annoyance/footgun in quinn, that leaks out to rpc.
When code that uses a quinn::SendStream is dropped, e.g. because of an error or because a future is dropped due to a timeout, finish is called on drop. If - which is pretty likely, this finish is not called in the middle of sending a length delimited message, from the remote side this is indistinguishable from a normal stream termination.
So e.g. if you have a local impl Stream<Item = Bytes>, you can't just translate this to a irpc request with a rx: spsc::Receiver<Bytes>. E.g. you try to send a stream of 10 blobs, remote for some reason only gets 9, you get a different hash.
The proper translation is to create an enum with an explicit Done case, and then on the server side fail unless you get the Done message. But this is quite tedious, you end up translating from local Stream to rpc protocol message T | Done and back on the recv side.
The following would be alternatives:
- have an explicit built in end of stream message, then translate the lack of this message to a RecvError::SenderClosed.
- change our quinn fork to not call finish on drop, but to call reset
Note that this is only relevant for the case where the update messages are not self-contained and there is no natural end of stream message. It is also only relevant for spsc streams.