Asynchronous Task

Process a domain event by triggering an asynchronous task or process.

Problem

In a bike rental domain, a renter may register and subsequently go through an onboarding workflow. This workflow is encapsulated as an orchestration that must be launched asynchronously.

Solution

Perform a hand-off in the event handler for the domain event to a separate task or process.

Example

The event model in figure 1 depicts the outlined bike rental scenario in the problem section:

figure 1

Figure 1 - Modeling asynchronous event processing

A newly registered renter is processed asynchronously by initiating an onboarding workflow.

The particulars of the onboarding workflow are not modeled in this example (only its commencement and completion is shown); typically those details are modeled as a distinct business flow elsewhere in the event model.

Awaiting the completion of an asynchronous task or process is outside the scope of this pattern; typically any interested components have to listen for a suitable event, such as OnboardingCompleted in figure 1.

This example uses Restate for defining and running external workflows. Other options include Temporal and Dapr Workflow.

Listing 1 shows a sample workflow definition:

@Workflow
public class OnboardingWorkflow {
    
    @Workflow
    public String run(WorkflowContext ctx, RenterDetails renter) {
        
        // This (potentially long-running) process executes the onboarding
        // workflow for a renter.

        return 'success';
    }
}

Listing 1 - Sample workflow definition

Listing 2 shows a possible implementation of the InitiateOnboarding command in an Axon event handler:

@EventHandler
public void on(RenterRegistered evt) {
    Client workflowEngine = Client.connect("<Workflow Engine Server URL>");
    OnboardingWorkflowClient.fromClient(
        workflowEngine, 
        evt.renterId
    ).submit(renterDetailsFrom(evt));
}

Listing 2 - Process a domain event by asynchronously launching an external workflow

Ensure that the hand-off is idempotent; in listing 2 the launch and execution of the onboarding workflow will only occur once for each renter (based on the renter identifier), as guaranteed by the workflow engine (Restate).