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(Async.shift *> 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]
Obtains the value of the Deferred
, or waits until it has been completed.
Obtains the value of the Deferred
, or waits until it has been completed.
The returned value may be canceled.
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 emptyDeferred
will block until theDeferred
is completed.get
on a completedDeferred
will always immediately return its content.complete(a)
on an emptyDeferred
will set it toa
, and notify any and all readers currently blocked on a call toget
.complete(a)
on aDeferred
that has already been completed will not modify its content, and result in a failedF
.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.