A purely functional synchronization primitive which represents a single value which may not yet be available.
A purely functional synchronization primitive which represents a single value which may not yet be available.
When created, a Deferred
is empty. It can then be completed exactly once,
and never be made empty again.
get
on an empty Deferred
will block until the Deferred
is completed.
get
on a completed Deferred
will always immediately return its content.
complete(a)
on an empty Deferred
will set it to a
, and notify any and
all readers currently blocked on a call to get
.
complete(a)
on a Deferred
that has already been completed will not modify
its content, and result in a failed F
.
Albeit simple, Deferred
can be used in conjunction with Ref to build
complex concurrent behaviour and data structures like queues and semaphores.
Finally, the blocking mentioned above is semantic only, no actual threads are blocked by the implementation.
- Companion
- object
Value members
Abstract methods
If this Deferred
is empty, sets the current value to a
, and notifies
any and all readers currently blocked on a get
.
If this Deferred
is empty, sets the current value to a
, and notifies
any and all readers currently blocked on a get
.
Note that the returned action may complete after the reference
has been successfully set: use F.start(r.complete)
if you want
asynchronous behaviour.
If this Deferred
has already been completed, the returned
action immediately fails with an IllegalStateException
. In the
uncommon scenario where this behavior is problematic, you can
handle failure explicitly using attempt
or any other
ApplicativeError
/MonadError
combinator on the returned
action.
Satisfies:
Deferred[F, A].flatMap(r => r.complete(a) *> r.get) == a.pure[F]