Channel
The Channel module provides high-performance message-passing channels for concurrent programming. Channels are the primary mechanism for communication between actors and parallel operations, similar to Go channels but with multiple variants for different use cases.
Channel Types
Kit provides several channel types optimized for different concurrency patterns:
Channel.spsc
Int -> Result (Channel a) ChannelError
Creates a Single-Producer Single-Consumer channel.
Lock-free and highest performance for single-threaded producer/consumer.
ch = Channel.spsc 10 |> Result.unwrap
Channel.mpsc
Int -> Result (Channel a) ChannelError
Creates a Multi-Producer Single-Consumer channel.
Thread-safe for multiple senders, one receiver.
ch = Channel.mpsc 100 |> Result.unwrap
Channel.spmc
Int -> Result (Channel a) ChannelError
Creates a Single-Producer Multi-Consumer channel.
Thread-safe for one sender, multiple receivers.
Channel.unbounded
() -> Result (Channel a) ChannelError
Creates an unbounded channel that grows as needed.
No capacity limit, but may use more memory.
ch = Channel.unbounded() |> Result.unwrap
Blocking Operations
Channel.send
Channel a -> a -> Result () ChannelError
Sends a value to the channel, blocking if full.
Returns
Err if the channel is closed.
Channel.send ch "hello"
Channel.recv
Channel a -> Result a ChannelError
Receives a value from the channel, blocking if empty.
Returns
Err if the channel is closed and empty.
match Channel.recv ch
| Ok msg -> println "Got: ${msg}"
| Err ChannelClosed -> println "Channel closed"
| Err e -> println "Error: ${e}"
Non-Blocking Operations
Channel.try-send
Channel a -> a -> Bool
Attempts to send without blocking.
Returns true if sent, false if full or closed.
if Channel.try-send ch "world" then
println "sent"
else
println "channel full"
Channel.try-recv
Channel a -> Option a
Attempts to receive without blocking.
Returns
Some value if available, None if empty.
match Channel.try-recv ch
| Some msg -> println msg
| None -> println "empty"
Timed Operations
Channel.recv-timeout
Channel a -> Int -> Option a
Receives with a timeout in milliseconds.
Returns
Some value if received, None if timed out.
match Channel.recv-timeout ch 1000
| Some msg -> println "got: ${msg}"
| None -> println "timed out after 1 second"
Status Functions
Channel.is-empty?
Channel a -> Bool
Returns true if the channel has no pending messages.
Channel.is-full?
Channel a -> Bool
Returns true if the channel is at capacity.
Always returns false for unbounded channels.
Channel.len
Channel a -> Int
Returns the number of messages currently in the channel.
Channel.capacity
Channel a -> Int
Returns the channel's capacity.
Returns -1 for unbounded channels.
Channel.close
Channel a -> ()
Closes the channel. No more sends allowed.
Receivers can still drain remaining messages.
Channel.close ch
Error Types
type ChannelError =
| CreateError { message: String }
| SendError { message: String }
| RecvError { message: String }
| ChannelClosed
| InvalidChannel
| ChannelError { message: String }
Complete Example
# Create a bounded SPSC channel
ch = Channel.spsc 10 |> Result.unwrap
# Send some messages
Channel.send ch "hello"
Channel.send ch "world"
# Receive messages
msg1 = Channel.recv ch |> Result.unwrap
msg2 = Channel.recv ch |> Result.unwrap
println "${msg1} ${msg2}" # => hello world
# Non-blocking check
match Channel.try-recv ch
| Some m -> println "more: ${m}"
| None -> println "channel empty"
# Cleanup
Channel.close ch