=begin pod

=TITLE class Channel

=SUBTITLE Thread-safe queue for sending values from producers to consumers

    class Channel { ... }

A Channel is a thread-safe queue that helps you to send a series of objects from
one or more producers to one or more consumers.

    my $c = Channel.new;
    await (^10).map: {
        start {
            my $r = rand;
            sleep $r;
            $c.send($r);
        }
    }
    $c.close;
    say $c.list;

=head1 Methods

=head2 method send

Defined as:

    method send(Channel:D: \item)

Usage:

    CHANNEL.send(ITEM)

Enqueues an item into the channel. Throws an exception of type
L<X::Channel::SendOnClosed> if the channel has been closed already.

=head2 method receive

Defined as:

    method receive(Channel:D:)

Usage:

   CHANNEL.receive

Receives and removes an item from the channel. It blocks if no item is
present, waiting for a C<send> from another thread.

Throws an exception of
type L<X::Channel::ReceiveOnClosed> if the channel has been closed, and the
last item has been removed already, or if C<close> is called while C<receive>
is waiting for an item to arrive.

If the channel has been marked as erratic with method C<fail>, and the last
item has been removed, throws the argument that was given to C<fail> as an
exception.

See method C<poll> for a non-blocking version that won't throw exceptions.

=head2 method poll

Defined as:

    method poll(Channel:D:)

Usage:

    CHANNEL.poll

Receives and removes an item from the channel. If no item is present, returns
C<Nil> instead of waiting.

See method C<receive> for a blocking version that properly responds to channel
closing and failure.

=head2 method close

Defined as:

    method close(Channel:D:)

Usage:

    CHANNEL.close

Close the channel. This makes subsequent C<send> calls die, as well as a
C<receive> call past the end of the queue,
and is a prerequisite for C<list> to terminate.

=head2 method list

Defined as:

    method list(Channel:D:) returns List:D

Usage:

    CHANNEL.list

Returns a list of all remaining items in the queue, and removes them from the
channel. This can only terminate once C<close> has been called.

=head2 method closed

Defined as:

    method closed(Channel:D:) returns Promise:D

Usage:

    CHANNEL.closed

Returns a promise that will be kept once the channel is closed by a call to
method C<close>.

=head2 method fail

Defined as:

    method fail(Channel:D: $error)

Usage:

    CHANNEL.fail

Closes the channel (that is, makes subsequent C<send> calls die), and enqueues
the error as the final element in the channel. Method C<receive> will throw
the error as an exception.

=head2 sub await

Defined as:

    multi sub await(Channel:D)
    multi sub await(*@)

Usage:

    await(CHANNEL)
    await(CHANNELS)

Waits until all of one or more channels has a value available, and returns
those values (it calls C<.receive> on the channel). Also works with
L<promises|/type/Promise>.

=end pod
