The implementation point for a custom suspended Async leaf (a timer, a socket read, a callback bridge, ...). A Pollable[A] is itself an Async[A], so it can be used wherever an Async[A] is expected.
Implementors define poll: when asked for its value, a pollable either returns the completed result (a value, or a failed Async) or, if it is still pending, stashes the supplied java.lang.Runnable and returns a pending Async (typically itself). When the value later becomes available it must invoke onComplete.run() to ask the scheduler to poll again.
Attempt to produce this computation's value. Returns the completed result if it is ready; otherwise registers onComplete (to be invoked when the value becomes available) and returns a still-pending Async.
Attempt to produce this computation's value. Returns the completed result if it is ready; otherwise registers onComplete (to be invoked when the value becomes available) and returns a still-pending Async.
A still-pending result is either this pollable itself (the common case) or a '''replacement''' pollable that represents the rest of the computation; the caller must direct its next poll at whatever pollable was returned. The built-in drivers (block, start, the interop runners) and every combinator follow this, so a conforming poll may hand back a new pollable at any suspension.
Returning the same identity means the caller may wait for the registered callback. Returning a distinct identity is synchronous progress: the caller must poll that replacement without waiting. An identity change is not a readiness event, so a caller or wrapper must not synthesize onComplete for it. Real callbacks may be stale, reentrant, or duplicated and are therefore coalescible wake permits rather than proof that a particular generation has completed.
Polling is a '''one-shot driver protocol''': a driver should keep polling only while poll returns a still-pending Pollable, and must stop as soon as it returns a terminal result — a raw value or a failed Async. The built-in drivers (block, start, and the interop runners) all follow this, so they never poll a settled computation again.
Re-polling a Pollable after it has returned a terminal result is outside the contract and is '''not''' guaranteed to be a pure re-observation: a continuation may run again and diagnostic state may be repeated. Drive computations through the built-in runners unless you are implementing this protocol yourself, in which case honor the stop-at-terminal rule.
Signal cancellation of the currently pending operation. Implementations that own cancellable work override this with an idempotent, non-blocking signal; computations without such work inherit the no-op. A running driver invokes this only when cancellation wins against completion.
Signal cancellation of the currently pending operation. Implementations that own cancellable work override this with an idempotent, non-blocking signal; computations without such work inherit the no-op. A running driver invokes this only when cancellation wins against completion.