Package org.apache.groovy.runtime.async

# Class DefaultAsyncChannel<T>

java.lang.Object
org.apache.groovy.runtime.async.DefaultAsyncChannel<T>

Type Parameters:
  `T` - the payload type

All Implemented Interfaces:
  `AsyncChannel<T>`, `Iterable<T>`

public final class DefaultAsyncChannel<T> extends Object implements AsyncChannel<T>
Default lock-based implementation of `AsyncChannel`.

Uses a `ReentrantLock` to coordinate access to the internal buffer and the waiting-sender/waiting-receiver queues. All operations return `Awaitable` immediately; the underlying `CompletableFuture` is completed asynchronously when matching counterparts arrive.

Every operation is arbitrated by a `SelectClaim`: the branches of a `ChannelSelect` share their select's claim, and a plain operation carries a private one. The claim is the sole owner of a parked operation's fate — a delivery commits it before it completes the future, and cancellation must commit it before it may touch the future — so a select over sends and receives on several channels commits exactly one transfer, and a losing branch never disturbs its channel.

Both waiting queues are concurrent deques so that a cancelled operation can withdraw itself without taking the channel lock: a `ChannelSelect` withdraws its losing branches from inside the winning channel's delivery, and taking a second channel's lock there could deadlock against a select completing on that channel.

Since:
  6.0.0
See Also:
  - `AsyncChannel`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `DefaultAsyncChannel()`
  `DefaultAsyncChannel(int capacity)`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `static DefaultAsyncChannel<Instant>`
  `after(long delay, TimeUnit unit)`
  Creates a timer channel: a capacity-1 channel that delivers one value, the `Instant` at which it fired, once `delay` has elapsed from this call, and then closes.
  `boolean`
  `close()`
  Closes this channel.
  `int`
  `getBufferedSize()`
  Returns the number of values currently buffered.
  `int`
  `getCapacity()`
  Returns this channel's buffer capacity.
  `boolean`
  `isClosed()`
  Returns `true` if this channel has been closed.
  `Iterator<T>`
  `iterator()`
  Returns a blocking iterator that receives values until the channel is closed and drained.
  `Awaitable<T>`
  `receive()`
  Receives the next value from this channel.
  `Awaitable<T>`
  `receiveIfUnclaimed(SelectClaim claim)`
  Receives the next value, but only if `claim` commits to this branch at the moment this channel would hand the value over.
  `Awaitable<Void>`
  `send(T value)`
  Sends a value through this channel.
  `Awaitable<Void>`
  `sendIfUnclaimed(T value, SelectClaim claim)`
  Offers `value`, but only if `claim` commits to this branch at the moment the channel could accept it: when a waiting receiver takes it, or when buffer space holds it.
  `String`
  `toString()`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

  ### Methods inherited from interface groovy.concurrent.AsyncChannel

  `filter, map, merge, split, tap`

  ### Methods inherited from interface java.lang.Iterable

  `forEach, spliterator`

- ## Constructor Details

  - ### DefaultAsyncChannel

    public DefaultAsyncChannel()

  - ### DefaultAsyncChannel

    public DefaultAsyncChannel(int capacity)

- ## Method Details

  - ### after

    public static DefaultAsyncChannel<Instant> after(long delay, TimeUnit unit)
    Creates a timer channel: a capacity-1 channel that delivers one value, the `Instant` at which it fired, once `delay` has elapsed from this call, and then closes. Closing the channel before it fires cancels the timer, so a timer that is no longer wanted holds no scheduler slot. A delay that is not positive has already elapsed, so the channel is returned already holding its instant and closed: it is ready to a receiver or a select at once, with no scheduler hop.

    Implementation of `AsyncChannel.after(long)`; not part of the channel contract.

    Parameters:
      `delay` - how long to wait before firing
      `unit` - the unit of `delay`
    Returns:
      the timer channel

  - ### getCapacity

    public int getCapacity()
    Description copied from interface: `AsyncChannel`
    Returns this channel's buffer capacity.
    Specified by:
      `getCapacity` in interface `AsyncChannel<T>`

  - ### getBufferedSize

    public int getBufferedSize()
    Description copied from interface: `AsyncChannel`
    Returns the number of values currently buffered.
    Specified by:
      `getBufferedSize` in interface `AsyncChannel<T>`

  - ### isClosed

    public boolean isClosed()
    Description copied from interface: `AsyncChannel`
    Returns `true` if this channel has been closed.
    Specified by:
      `isClosed` in interface `AsyncChannel<T>`

  - ### send

    public Awaitable<Void> send(T value)
    Description copied from interface: `AsyncChannel`
    Sends a value through this channel.

    The returned `Awaitable` completes when the value has been delivered to a receiver or buffered. Sending to a closed channel fails immediately with `ChannelClosedException`.

    Specified by:
      `send` in interface `AsyncChannel<T>`
    Parameters:
      `value` - the value to send; must not be `null`
    Returns:
      an Awaitable that completes when the send succeeds

  - ### sendIfUnclaimed

    public Awaitable<Void> sendIfUnclaimed(T value, SelectClaim claim)
    Offers `value`, but only if `claim` commits to this branch at the moment the channel could accept it: when a waiting receiver takes it, or when buffer space holds it. A group of offers sharing one claim (the branches of a `ChannelSelect`) commits exactly one between them; an offer whose claim was committed elsewhere is retired without any effect on the channel — no buffered residue, no lingering waiting sender.

    Internal support for `ChannelSelect`; not part of the channel contract.

    Parameters:
      `value` - the value offered for transfer
      `claim` - the claim shared by the competing offers
    Returns:
      an Awaitable that completes when the send committed, or is cancelled if the claim was taken elsewhere first

  - ### receive

    public Awaitable<T> receive()
    Description copied from interface: `AsyncChannel`
    Receives the next value from this channel.

    The returned `Awaitable` completes when a value is available. Receiving from a closed, empty channel fails with `ChannelClosedException`.

    Specified by:
      `receive` in interface `AsyncChannel<T>`
    Returns:
      an Awaitable that yields the next value

  - ### receiveIfUnclaimed

    public Awaitable<T> receiveIfUnclaimed(SelectClaim claim)
    Receives the next value, but only if `claim` commits to this branch at the moment this channel would hand the value over. The claim is resolved under the channel lock immediately before the value is dequeued, so a group of offers sharing one claim (the branches of a `ChannelSelect`) takes exactly one value between them: a branch that loses the claim never touches its channel's contents and is completed as cancelled.

    Internal support for `ChannelSelect`; not part of the channel contract.

    Parameters:
      `claim` - the claim shared by the competing offers
    Returns:
      an Awaitable that yields the next value, or is cancelled if the claim was taken elsewhere first

  - ### close

    public boolean close()
    Description copied from interface: `AsyncChannel`
    Closes this channel. Idempotent.

    Buffered values remain receivable. Pending senders fail with `ChannelClosedException`. After all buffered values are drained, subsequent receives also fail.

    Specified by:
      `close` in interface `AsyncChannel<T>`
    Returns:
      `true` if this call actually closed the channel

  - ### iterator

    public Iterator<T> iterator()
    Returns a blocking iterator that receives values until the channel is closed and drained. Each `next()` call blocks until a value is available. `ChannelClosedException` signals end-of-iteration.
    Specified by:
      `iterator` in interface `Iterable<T>`

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `Object`