Skip to content

Zero-capacity channels #436

Closed
Closed
@ghost

Description

While we can't implement zero-capacity channels based on futures as faithfully as they are in crossbeam-channel and Go, we can do something very similar. Here's a proposal.

Our zero-capacity channel could be implemented as a channel that has the capacity of 1, except that every send operation does not complete until its message is received.

The problem here is that send operations are not cleanly cancelable. Once a send operation has put its message into the channel, a receive operation can take it. If the Send future is then dropped, the send operation is not really canceled because someone has already picked up the message.

This issue will come up if we're selecting over send operations:

futures::select! {
    _ = s1.send(msg1) => {}
    _ = s2.send(msg2) => {}
}

Here it's possible for both send operations to be executed simultaneously. But maybe that's fine and not a big issue since selection over send operation is rare.

Fortunately, selection over receive operation is still cleanly cancellable:

futures::select! {
    msg1 = r1.recv() => {}
    msg2 = r2.recv() => {}
}

Exactly one receive operation will complete here, which is what the user would probably expect. We can't make the same guarantee about send operations on zero-capacity channels, though.

Is this an acceptable compromise? What does everyone think?

cc @matklad

Metadata

Metadata

Assignees

No one assigned

    Labels

    api designOpen design questions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions