Skip to content

Channels

Channels provide message passing between tasks.

Basic Usage

wyn
var ch = Task.channel(10)       // buffered channel, capacity 10

Task.send(ch, 42)
Task.send(ch, 100)

var first = Task.recv(ch)       // 42
var second = Task.recv(ch)      // 100

Producer / Consumer

wyn
fn producer(ch: int, n: int) -> int {
    for i in 0..n {
        Task.send(ch, i * i)
    }
    return 0
}

fn main() -> int {
    var ch = Task.channel(100)
    var f = spawn producer(ch, 10)

    for i in 0..10 {
        println(Task.recv(ch).to_string())
    }
    await f
    return 0
}

Messages are received in FIFO order.

Select (Multiple Channels)

Wait on multiple channels simultaneously using Task.select_2 or Task.select_3. Returns the 0-based index of the first channel with data.

wyn
var ch1 = Task.channel(8)
var ch2 = Task.channel(8)

// In another coroutine, someone sends to ch2
spawn sender(ch2, 42, 100)

// Wait for either channel
var ready = Task.select_2(ch1, ch2)
if ready == 0 {
    var val = Task.recv(ch1)
    println("got from ch1: " + val.to_string())
} else if ready == 1 {
    var val = Task.recv(ch2)
    println("got from ch2: " + val.to_string())
}
  • Task.select_2(ch1, ch2) — wait on 2 channels
  • Task.select_3(ch1, ch2, ch3) — wait on 3 channels
  • Returns -1 if all channels are closed
  • Inside a coroutine, select yields instead of blocking

Non-blocking Try Receive

wyn
var ch = Task.channel(8)
Task.send(ch, 42)

var out = 0
if Task.try_recv(ch, out) == 1 {
    println("got: " + out.to_string())
} else {
    println("channel empty")
}

MIT License