Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There are some places where instead of asynchronously sending a value to a channel (
sender.send(value).await
), we asynchronously wait for the ability to send to a channel and then immediately send the value after:This API allows the opportunity to defer certain processing until the moment of the actual send. The problem is its usage is a bit fiddly and error-prone. Notably, if the code waiting for the ability to send decides to give up waiting, or if it finishes waiting but then decides not to send anything, it needs to explicitly cancel the operation (
sender.cancel()
). Failing to cancel can lead to broken coordination when there are multiple senders waiting to send.This PR introduces a simpler API:
If the future returned by
wait_sendable()
is dropped before completion, the operation is automatically canceled. If it completes, it produces aSendOnce
struct which can be used to send up to one value via itstry_send()
method. If theSendOnce
is dropped without sending anything, the operation is automatically canceled. Basically it makes the API hard to misuse.Note that the method is named
try_send()
and notsend()
because the channel could still become full after obtaining theSendOnce
, if another sender were to send to the channel.This PR also uses the new API in a couple of places.