txt: ## channel.md
  class Channel
  
  Thread-safe queue for sending values from producers to consumers
  
  ```raku
  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. Each object will arrive at only one such consumer, selected by the scheduler. If there is only one consumer and one producer, the order of objects is guaranteed to be preserved. Sending on a `Channel` is non-blocking.
  
  ```raku
  my $c = Channel.new;
  await (^10).map: {
      start {
          my $r = rand;
          sleep $r;
          $c.send($r);
      }
  }
  $c.close;
  say $c.list;
  ```
  
  Further examples can be found in the [concurrency page](/language/concurrency#Channels)
  
  # [Methods](#class_Channel "go to top of document")[§](#Methods "direct link")
  
  ## [method send](#class_Channel "go to top of document")[§](#method_send "direct link")
  
  ```raku
  method send(Channel:D: \item)
  ```
  
  Enqueues an item into the `Channel`. Throws an exception of type [`X::Channel::SendOnClosed`](/type/X/Channel/SendOnClosed) if the `Channel` has been closed already. This call will **not** block waiting for a consumer to take the object. There is no set limit on the number of items that may be queued, so care should be taken to prevent runaway queueing.
  
  ```raku
  my $c = Channel.new;
  $c.send(1);
  $c.send([2, 3, 4, 5]);
  $c.close;
  say $c.list; # OUTPUT: «(1 [2 3 4 5])␤»
  ```
  
  ## [method receive](#class_Channel "go to top of document")[§](#method_receive "direct link")
  
  ```raku
  method receive(Channel:D:)
  ```
  
  Receives and removes an item from the `Channel`. It blocks if no item is present, waiting for a `send` from another thread.
  
  Throws an exception of type [`X::Channel::ReceiveOnClosed`](/type/X/Channel/ReceiveOnClosed) if the `Channel` has been closed, and the last item has been removed already, or if `close` is called while `receive` is waiting for an item to arrive.
  
  If the `Channel` has been marked as erratic with method `fail`, and the last item has been removed, throws the argument that was given to `fail` as an exception.
  
  See method `poll` for a non-blocking version that won't throw exceptions.
  
  ```raku
  my $c = Channel.new;
  $c.send(1);
  say $c.receive; # OUTPUT: «1␤»
  ```
  
  ## [method poll](#class_Channel "go to top of document")[§](#method_poll "direct link")
  
  ```raku
  method poll(Channel:D:)
  ```
  
  Receives and removes an item from the `Channel`. If no item is present, returns [`Nil`](/type/Nil) instead of waiting.
  
  ```raku
  my $c = Channel.new;
  Promise.in(2).then: { $c.close; }
  ^10 .map({ $c.send($_); });
  loop {
      if $c.poll -> $item { $item.say };
      if $c.closed  { last };
      sleep 0.1;
  }
  ```
  
  See method `receive` for a blocking version that properly responds to `Channel` closing and failure.
  
  ## [method close](#class_Channel "go to top of document")[§](#method_close "direct link")
  
  ```raku
  method close(Channel:D:)
  ```
  
  Close the `Channel`, normally. This makes subsequent `send` calls die with [`X::Channel::SendOnClosed`](/type/X/Channel/SendOnClosed). Subsequent calls of `.receive` may still drain any remaining items that were previously sent, but if the queue is empty, will throw an [`X::Channel::ReceiveOnClosed`](/type/X/Channel/ReceiveOnClosed) exception. Since you can produce a [`Seq`](/type/Seq) from a `Channel` by contextualizing to array with `@()` or by calling the `.list` method, these methods will not terminate until the `Channel` has been closed. A [whenever](/language/concurrency#whenever)-block will also terminate properly on a closed `Channel`.
  
  ```raku
  my $c = Channel.new;
  $c.close;
  $c.send(1);
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::Channel::SendOnClosed: Cannot send a message on a closed channel␤»
  
  ```
  
  Please note that any exception thrown may prevent `.close` from being called, this may hang the receiving thread. Use a [LEAVE](/language/phasers#LEAVE) phaser to enforce the `.close` call in this case.
  
  ## [method list](#class_Channel "go to top of document")[§](#method_list "direct link")
  
  ```raku
  method list(Channel:D:)
  ```
  
  Returns a list based on the [`Seq`](/type/Seq) which will iterate items in the queue and remove each item from it as it iterates. This can only terminate once the `close` method has been called.
  
  ```raku
  my $c = Channel.new; $c.send(1); $c.send(2);
  $c.close;
  say $c.list; # OUTPUT: «(1 2)␤»
  ```
  
  ## [method closed](#class_Channel "go to top of document")[§](#method_closed "direct link")
  
  ```raku
  method closed(Channel:D: --> Promise:D)
  ```
  
  Returns a promise that will be kept once the `Channel` is closed by a call to method `close`.
  
  ```raku
  my $c = Channel.new;
  $c.closed.then({ say "It's closed!" });
  $c.close;
  sleep 1;
  ```
  
  ## [method fail](#class_Channel "go to top of document")[§](#method_fail "direct link")
  
  ```raku
  method fail(Channel:D: $error)
  ```
  
  Closes the `Channel` (that is, makes subsequent `send` calls die), and enqueues the error to be thrown as the final element in the `Channel`. Method `receive` will throw that error as an exception. Does nothing if the `Channel` has already been closed or `.fail` has already been called on it.
  
  ```raku
  my $c = Channel.new;
  $c.fail("Bad error happens!");
  $c.receive;
  CATCH { default { put .^name, ': ', .Str } };
  # OUTPUT: «X::AdHoc: Bad error happens!␤»
  ```
  
  ## [method Capture](#class_Channel "go to top of document")[§](#method_Capture "direct link")
  
  ```raku
  method Capture(Channel:D: --> Capture:D)
  ```
  
  Equivalent to calling [`.List.Capture`](/type/List#method_Capture) on the invocant.
  
  ## [method Supply](#class_Channel "go to top of document")[§](#method_Supply "direct link")
  
  ```raku
  method Supply(Channel:D:)
  ```
  
  This returns an `on-demand` [`Supply`](/type/Supply) that emits a value for every value received on the `Channel`. `done` will be called on the [`Supply`](/type/Supply) when the `Channel` is closed.
  
  ```raku
  my $c = Channel.new;
  my Supply $s1 = $c.Supply;
  my Supply $s2 = $c.Supply;
  $s1.tap(-> $v { say "First $v" });
  $s2.tap(-> $v { say "Second $v" });
  ^10 .map({ $c.send($_) });
  sleep 1;
  ```
  
  Multiple calls to this method produce multiple instances of Supply, which compete over the values from the `Channel`.
  
  ## [sub await](#class_Channel "go to top of document")[§](#sub_await "direct link")
  
  ```raku
  multi await(Channel:D)
  multi await(*@)
  ```
  
  Waits until all of one or more `Channel`s has a value available, and returns those values (it calls `.receive` on the `Channel`). Also works with [`Promise`](/type/Promise)s.
  
  ```raku
  my $c = Channel.new;
  Promise.in(1).then({$c.send(1)});
  say await $c;
  ```
  
  Since 6.d, it no longer blocks a thread while waiting.
  
  # [Typegraph](# "go to top of document")[§](#typegraphrelations "direct link")
  
  Type relations for `Channel`
  
  
  
  raku-type-graph
  
  
  
  Channel
  Channel
  
  
  Any
  Any
  
  
  Channel->Any
  
  
  
  Mu
  Mu
  
  
  Any->Mu
  
  [Expand chart above](/assets/typegraphs/Channel.svg)
  