Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Receive from either channel

select_recv waits for a message from either of two channels. Their message types may differ; match the returned Selected value to find which one arrived. Both receivers are borrowed implicitly; explicit & arguments also work.

type ChannelSelectionError = RecvError | SelectError | SendError[i64] | SendError[str] | AllocError

def main() -> Result[(), IoError | ChannelSelectionError]:
    commands, control = channel[str](1)?
    numbers, data = channel[i64](1)?
    commands.send("stop")?
    numbers.send(42)?
    match select_recv(control, data)?:
        case Selected.First(command):
            print(command)?
        case Selected.Second(number):
            print(number)?
    print(data.recv()?)?
    Ok(())
stop
42

When both channels have messages, the first takes priority. The other message stays in its queue. This can be useful for shutdown commands, but constant traffic on the first channel can starve the second.

select_recv_nowait(&first, &second) returns SelectError.Empty if neither has a message. select_recv_timeout_ms(&first, &second, milliseconds) instead waits up to that budget and may return SelectError.TimedOut.

Selection skips a drained channel whose senders have all gone away. It reports SelectError.Disconnected only when both channels are drained and disconnected. The receivers remain yours after every outcome.