No success with persistAll in CommandHandler


(Niklasuhrberg) #1

In my application a couple of commands naturally gives rise to two instead of just one domain event.
Therefore instead of the normal

return ctx.thenPersist(be,
                            // Then once the event is successfully persisted, we respond with done.
                            evt -> ctx.reply(Done.getInstance())
                    );

I tried this:

return ctx.thenPersistAll(Arrays.asList(de, be));

Now two things happen:

  1. The events get persisted and my eventhandlers get invoked just fine.
  2. After 5 seconds I get an AskTimeoutException

I can’t get my head around this. As a workaround, I packed all the information into one single event so I get the (seemingly) most common style and everything works perfectly.

I don’t have the stacktrace right now but I figured this might be enough info for a real expert.
The call that I believe is subject to the AskTimeout originates from an event subscriber with atMostOnce semantics: (I’m not an expert on Lagom, bare with me on this one. But at least it gets the job done.)

    private  CompletionStage processEvent2(CreditApplicationEvent evt) {
        CompletableFuture rv = CompletableFuture.supplyAsync(new Supplier<CreditApplicationEvent>() {

            public CreditApplicationEvent get() {
                String halt = "";
                if (evt instanceof AccountsDataNeededEvent) {
                    AccountsDataNeededEvent at = (AccountsDataNeededEvent) evt;
                    LOGGER.debug(String.format("Requesting accounts data for %s", evt.UUIDString()));
                    accountsService.evaluate(at.country, at.govId).invoke()
                            .thenApply(ar -> {

                                    LOGGER.debug(String.format("Feeding accountsdata for %s", evt.UUIDString()));
                                    return creditApplicationService.accountsData()
                                            .invoke(new AccountsResponseWithUUID(ar, at.uuid)).toCompletableFuture();

                            });
                }

                return evt;
            }
        });

        return rv;
    }

So my question is basically: How should I code to be able to use multiple domain events. It’s going to be a real pain not having this feature at hand.


(Niklasuhrberg) #2

I solved this after reading https://github.com/lagom/lagom/issues/919

It was dead simple, but if you’re new to this it’s easy to get confused by the asymmetry between the case of one vs multiple events.

Correct code:

    return ctx.thenPersistAll(Arrays.asList(de, be),
         () -> ctx.reply(Done.getInstance()));