Axon 4: EventSourcingHandler not triggered when applying event from a different thread

喜欢而已 提交于 2019-12-24 03:42:28

问题


I've encountered a little issue with command handling in Axon 4.

Let say I have an aggregate that need to call an external service when handling a command.

The external service uses an asynchronous client (vertx tcp client + rxjava), so the response is given in a different thread than the one that created the aggregate instance.

I want to apply an event given the result of my service, but it does not work because the AggregateLifecycle.apply() call is on a different thread...

How can I "transfert" the scope of the aggregate ?

Here is a little exemple of what I want to do (uses rxjava 2 and lombok):

The aggregate:

@Slf4j
@Aggregate
@NoArgsConstructor
public class MyAggregate {

    @AggregateIdentifier
    private String id;

    @CommandHandler
    public MyAggregate(CreationCommand creationCommand) {
        Single.just("some data")
                .observeOn(Schedulers.computation()) // <- comment this line and the test pass, uncomment and it fail because apply is on another thread ?
                .subscribe((s, throwable) -> apply(new AggregateCreatedEvent(creationCommand.getId())));
    }

    @EventSourcingHandler
    public void on(AggregateCreatedEvent event) {
        this.id = event.getId();
    }
}

@Value class CreationCommand { String id; }
@Value class AggregateCreatedEvent { String id;}

And the test:

public class MyAggregateTest {

    AggregateTestFixture<MyAggregate> testFixture = new AggregateTestFixture<>(MyAggregate.class);

    @Test
    public void test() {
        testFixture.givenNoPriorActivity()
                .when(new CreationCommand("123"))
                .expectEvents(new AggregateCreatedEvent("123"));
    }
}

Here is the error I've got:

java.lang.IllegalStateException: Cannot request current Scope if none is active

回答1:


The event must be applied in the thread that manages that unit of work, in this case the CommandHandler. Axon provides its own mechanisms for asynchronous operations. The commandBus accepts commands asynchronously, and events are processed by the event processors asynchronously. There's nothing to be gained from also implementing your CommandHandler asynchronously, and in any case, it's not supported at this time.

All the data that you need to apply the event should normally be available in the command or in the aggregate state, not from additional external sources.

This is probably What you want your command handler to look like:

@CommandHandler
public MyAggregate(CreationCommand creationCommand) {
    apply(new AggregateCreatedEvent(creationCommand.getId());
}


来源:https://stackoverflow.com/questions/54036482/axon-4-eventsourcinghandler-not-triggered-when-applying-event-from-a-different

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!