Axon 4:在应用来自其他线程的事件时未触发EventSourcingHandler

时间:2019-01-04 09:49:07

标签: rx-java2 axon

我在Axon 4中遇到了命令处理方面的小问题。

假设我有一个汇总,在处理命令时需要调用外部服务。

外部服务使用异步客户端(vertx tcp客户端+ rxjava),因此响应在与创建聚合实例的线程不同的线程中给出。

鉴于服务的结果,我想应用一个事件,但由于AggregateLifecycle.apply()调用在另一个线程上而无法使用...

如何“转移”汇总范围?

以下是我想做的事的一个例子(使用rxjava 2和lombok):

总计:

@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;}

测试:

public class MyAggregateTest {

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

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

这是我遇到的错误:

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

1 个答案:

答案 0 :(得分:1)

该事件必须在管理该工作单元的线程(在本例中为CommandHandler)中应用。 Axon提供了自己的异步操作机制。 commandBus异步接受命令,事件由事件处理器异步处理。异步实现CommandHandler也无济于事,无论如何,目前不支持。

通常,在命令中或在聚合状态下,应具有应用该事件所需的所有数据,而不是从其他外部来源获得。

这可能是您希望命令处理程序看起来像的样子:

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