Channel elements are FIFO queues for binary messages. A channel physically lives on a particular host. It supports a ‘send’ operation which pushes a new binary message to the queue, and a ‘receive’ operation which removes the next binary message from the queue.
On creation, channels can be configured to buffer a fixed non-negative number of messages. When the buffer is full, send operations block until a message is received. Receive operations, on the other hand, block if there are no pending messages in the buffer, until the next send operation is performed.
Channels are created using the anchor's MakeChan
method:
MakeChan(n int) (Chan, error)
For instance,
ch, err := anchor.MakeChan(0) if err != nil { … // this anchor is already busy }
An application error will be returned only if the anchor already has an element attached to it. The integer parameter specifies the number of messages the channel will buffer. This must be a non-negative integer.
Interacting with the channel is done using the channel element's interface:
type Chan interface { Send() (io.WriteCloser, error) Recv() (io.ReadCloser, error) Close() error Stat() ChanStat Scrub() }
The Scrub
method will forcefully abort and discard the
channel element, even if messages are pending in the channel's buffer.
The send/receive mechanism transports io.ReadWriteCloser
pipes between the sender and the receiver. The sender gets the write end
and the receiver gets the read end of the pipe.
To send a message, the user invokes Send
. If the channel
has been closed or aborted, a non-nil application error is returned. Otherwise,
a new pipe is created. Send attempts to send the pipe itself through the
channel. It will block until there is space in the channel buffer or there is
a matching call to Receive
.
When Send
unblocks it returns an io.WriteCloser
wherein
the user writes the content of the message and closes the stream to indicate end
of message.
w, err := ch.Send() if err != nil { … // channel has been closed } w.Write(msg) w.Close()
To receive a message, the user invokes Recv
. The operation blocks
until there is a pipe in the channel buffer or a matching call to Send
.
Receive will return an application error if the channel has been closed. Otherwise
it returns the reader end of the pipe received.
Channels can be closed synchronously with the Close
method.
The closure event will be communicated to the receiver after all pending messages
have been received. Close
returns an application error only if the
channel has already been clsoed.
An alternative method of closing the channel is to invoke Scrub
.
This will abort the channel and discard any pending messages.
The Stat
method can be called asynchronously to retrieve the
current state of the channel. The returned structure includes the channel capacity,
whether the channel has been closed or aborted, the number of messages sent
and received. (The difference of sent and received messages is the count of messages
pending reception in the channel buffer.)
type ChanStat struct { Cap int Closed bool Aborted bool NumSend int NumRecv int }