public interface AsyncChannel<T>
extends Iterable
An asynchronous channel for inter-task communication with optional buffering.
A channel coordinates producers and consumers without exposing explicit locks or shared mutable state, following the CSP (Communicating Sequential Processes) paradigm popularized by Go's channels.
Channels support both unbuffered (rendezvous) and buffered modes:
create() or create(0). Each
send suspends until a matching receive arrives.create(n). Values are enqueued until the
buffer fills, then senders suspend.
Channels implement Iterable, so they work with for await
and regular for loops — iteration yields received values until the
channel is closed and drained:
def ch = AsyncChannel.create(2)
async { ch.send('a'); ch.send('b'); ch.close() }
for await (item in ch) {
println item // prints 'a', then 'b'
}
T - the payload type| Type Params | Return Type | Name and description |
|---|---|---|
|
public static AsyncChannel<Instant> |
after(long millis)Creates a timer channel: a capacity-1 channel that delivers a single value, the Instant at which it fired, once millis has
elapsed from this call, and then closes. |
|
public static AsyncChannel<Instant> |
after(Duration duration)Creates a timer channel that fires once duration has elapsed;
see after(long). |
|
public boolean |
close()Closes this channel. |
<T> |
public static AsyncChannel<T> |
create()Creates an unbuffered (rendezvous) channel. |
<T> |
public static AsyncChannel<T> |
create(int capacity)Creates a channel with the specified buffer capacity. |
|
public AsyncChannel<T> |
filter(Predicate<T> predicate)Returns a new channel that passes only elements matching the predicate. |
|
public int |
getBufferedSize()Returns the number of values currently buffered. |
|
public int |
getCapacity()Returns this channel's buffer capacity. |
|
public boolean |
isClosed()Returns true if this channel has been closed. |
<R> |
public AsyncChannel<R> |
map(Function<T, R> transform)Returns a new channel that transforms each element using the function. |
|
public AsyncChannel<T> |
merge(AsyncChannel<? extends T> other)Returns a new channel that receives values from both this channel and the other channel. |
|
public Awaitable<T> |
receive()Receives the next value from this channel. |
|
public Awaitable<Void> |
send(T value)Sends a value through this channel. |
|
public List<AsyncChannel<T>> |
split(Predicate<T> predicate)Returns two new channels: elements matching the predicate go to the first, non-matching to the second. |
|
public AsyncChannel<T> |
tap(AsyncChannel<T> tap)Returns a new channel that receives all values from this channel while also sending a copy of each value to the tap channel. |
| Methods inherited from class | Name |
|---|---|
interface Iterable |
forEach, iterator, spliterator |
Creates a timer channel: a capacity-1 channel that delivers a single
value, the Instant at which it fired, once millis has
elapsed from this call, and then closes.
Its purpose is to make a deadline a branch of a ChannelSelect,
the way Go's time.After does, rather than an exception thrown
around the whole select by Awaitable.orTimeout:
def result = await ChannelSelect.from(work, AsyncChannel.after(100)).select()
if (result.index == 1) {
// timed out: result.value is the Instant the timer fired
}
As a channel, a timer composes with everything a select offers: several
timers give per-branch deadlines, a timer may be guarded with
ChannelSelect.Offer#when, and ChannelSelect.fair and
ChannelSelect.random treat it like any other ready branch.
The clock starts now, not at the first receive, so a timer created once and reused across selects is a fixed deadline shared by every round. For a per-round timeout that re-arms on each call of a select that is held and reused, use the timer offer ChannelSelect.after instead. A timer that loses a select keeps its value: it fires all the same and holds the instant until received. Once the value has been taken, further receives fail with ChannelClosedException rather than waiting forever, and isClosed() reports that the timer has fired. Closing a timer before it fires cancels it. A delay that is not positive has already elapsed, so the channel is returned already holding its instant: it is ready at once, which suits a deadline computed from an absolute time that has already passed.
millis - how long to wait before firing, in milliseconds Creates a timer channel that fires once duration has elapsed;
see after(long).
duration - how long to wait before firingCloses this channel. Idempotent.
Buffered values remain receivable. Pending senders fail with ChannelClosedException. After all buffered values are drained, subsequent receives also fail.
true if this call actually closed the channelCreates an unbuffered (rendezvous) channel.
Creates a channel with the specified buffer capacity.
capacity - the maximum buffer size; 0 for unbufferedReturns a new channel that passes only elements matching the predicate.
predicate - the filter functionReturns the number of values currently buffered.
Returns this channel's buffer capacity.
Returns true if this channel has been closed.
Returns a new channel that transforms each element using the function.
transform - the mapping functionR - the output element typeReturns a new channel that receives values from both this channel and the other channel. Values are interleaved as they arrive. The output closes when both inputs are exhausted.
other - the channel to merge withReceives the next value from this channel.
The returned Awaitable completes when a value is available. Receiving from a closed, empty channel fails with ChannelClosedException.
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.
value - the value to send; must not be nullReturns two new channels: elements matching the predicate go to the first, non-matching to the second. Both are closed when this channel is exhausted.
predicate - the split conditionReturns a new channel that receives all values from this channel while also sending a copy of each value to the tap channel. Useful for logging, monitoring, or forking a side pipeline.
tap - the channel to send copies to