Synchronized REST frontend with multiple service instances

Hello everyone,

My goal is to provide the user with a REST interface where he can send an Upload, that will trigger events across several different aggregates in the backend, and then block the request until I know the upload processing is finished and a projection is updated.

So, in my controller I send the command and block on a confirmation SubscriptionQuery:

private Upload handleUpload(Upload upload) { SubscriptionQueryResult<Boolean, Boolean> blockingQuery = queryGateway.subscriptionQuery(new IsUploadFinished(upload.getId()), Boolean.class, Boolean.class); commandGateway.sendAndWait(...); blockingQuery.updates().blockFirst(); return productUpload; }

And then I have a Saga that listens to an event for the Upload, dispatches commands to different aggregates and collects the resulting events.
Once the Saga knows the processing is finished it sends an Event to signal the processing of the Upload is finished:


@SagaEventHandler(associationProperty = "id")
public void handle(...) {
    [...]
    if (isSagaFinished()) {
        commandGateway.send(ConfirmUpload());
    }
} 

And then in my projection I emit an update to the "IsUploadFinished" query once the projection has processed the event:

Hi Alex,

Just a short pointer toward the direction I solved the same sort of issue.

I extended the CommandGateway and made a blocking implementation which waits until the subscribing query gets a result, so all that logic is moved to that implementation.

Besides that we had to configure the load balancer to use sticky sessions, so when the user post a createCommand it will be handled by the same node and wait until the result is visible on that node.

It works fine, also for use in tests the blockingCommandGateway is nice to use in stead of polling using Awaitillity.

Regards,

Frank