In workflows, we often create Deferred<T> object using the workflow functions:

  • dispatch (on new task or new / existing workflows)
  • receive (on channels)
  • timer

The creation of a deferred object is always asynchronous: it does not block the progress of the workflow.

Waiting for completion

We can wait for the completion of a Deferred<T> by applying the await method to it:

At each await() method, the workflow will stop on the line, up to the deferred completion.

Some exceptions can be thrown when waiting for a Deferred<T> completion. See here for more details.

Getting status

Deferred has some self-explanatory non-blocking methods to retrieve its current status:

  • isOngoing()
  • isUnknown()*
  • isCanceled()
  • isFailed()
  • isCompleted()

*The Unknown status is given when dispatching a method on a workflow stub created by getWorkflowById, with an id targeting a workflow that has never existed or is already completed or canceled.

A Deferred<T> status will be updated as the workflow progresses. For example, if service::handle is processed in 20 seconds:

Combining Deferred

A powerful feature of Deferred<T> is that they can be logically combined to create a new one, using io.infinitic.workflows.or and io.infinitic.workflows.and functions. This allow us to easily code requirement such as: let's wait for a confirmation signal, but not more that 2 days.

For example:

The return value depends on the operator:

  • or will return the return value of the first completed deferred
  • and will return the list of all completed deferred

If an exception occurs:

  • or will throw an exception relative to the last failed/canceled deferred
  • and will throw an exception relative to the first failed/canceled deferred
Inline Tasks

New version 0.11.2!