Использование EventScheduler не запускает обработчики событий в Aggregate - PullRequest
1 голос
/ 21 января 2020

Когда я запускаю запланированное событие с помощью команды, я не вижу ожидаемый триггер обработчика событий. Я пытаюсь изолировать одноразовую бизнес-транзакцию в Saga, в то же время позволяя получать агрегаты для обработки событий, чтобы иметь возможность воспроизводить изменения состояния.


Я настроил следующее SimpleEventScheduler.

@Bean
public SimpleEventScheduler simpleEventScheduler(EventBus eventBus) {
    return SimpleEventScheduler.builder()
        .eventBus(eventBus)
        .scheduledExecutorService(scheduledExecutorService())
        .build();
    }

private ScheduledExecutorService scheduledExecutorService() {
    return Executors.unconfigurableScheduledExecutorService(Executors.newSingleThreadScheduledExecutor());
}

У меня есть смоделированный агрегат, который имеет @CommandHandler

@CommandHandler
public Letter(ScheduleLetterCommand cmd, EventScheduler scheduler) {
    String id = cmd.getLetterId();
    log.info("Received schedule command for letter id {}", id);
    ScheduleToken scheduleToken = scheduler.schedule(Duration.ofSeconds(5), new BeginSendLetterEvent(id, LetterEventType.BEGIN_SEND));
    AggregateLifecycle.apply(new LetterScheduledEvent(id, LetterEventType.SCHEDULED, scheduleToken));
}

и два @EventSourcingHandler

@EventSourcingHandler
public void on(BeginSendLetterEvent event) {
    log.info("Letter sending process started {} {}", event.getLetterId(), event.getEventType());
    scheduleToken = null;
}

@EventSourcingHandler
public void on(LetterSentEvent event) {
    log.info("Letter sent {} {}", event.getLetterId(), event.getEventType());
    this.sent = true;
}

У меня есть сага, которая занимается некоторыми "делами" logi c ', когда BeginSendLetterEvent запущен и публикует LetterSentEvent.


@Saga
@Slf4j
public class LetterSchedulingSaga {

    private EventGateway eventGateway;

    public LetterSchedulingSaga() {
        //Axon requires empty constructor
    }

    @StartSaga
    @EndSaga
    @SagaEventHandler(associationProperty = "letterId")
    public void handle(BeginSendLetterEvent event) {
        log.info("Sending letter {}...", event.getLetterId());
        eventGateway.publish(new LetterSentEvent(event.getLetterId(), LetterEventType.SENT));
    }

    @Autowired
    public void setEventGateway(EventGateway eventGateway) {
        this.eventGateway = eventGateway;
    }
}

Вот мой вывод:

com.flsh.web.LetterScheduler            : Received request to schedule letter
com.flsh.web.LetterScheduler            : Finished request to schedule letter
com.flsh.axon.Letter                    : Received schedule command for letter id b7338082-e0e1-4ba0-b137-c7ff92afe3a1
com.flsh.axon.Letter                    : LetterScheduledEvent b7338082-e0e1-4ba0-b137-c7ff92afe3a1 SCHEDULED
com.flsh.axon.LetterSchedulingSaga      : Sending letter b7338082-e0e1-4ba0-b137-c7ff92afe3a1...

Дело в том, что я не вижу выше двух обработчики событий срабатывают вообще. Может кто-то видит, что я здесь делаю не так? :) Любая помощь приветствуется ...

Если это неправильный способ использования Sagas и обработчиков событий, пожалуйста, дайте мне знать. Я понимаю, что мой элементарный пример не способствует хорошей модели предметной области.

1 Ответ

2 голосов
/ 21 января 2020

Краткий ответ на вашу проблему @ GoldFi sh состоит в том, что вы ожидаете обработать события в вашей Командной модели.

Агрегат в терминах Аксона - это компонент обработки команд, так как он является частью ваша командная модель, когда вы думаете о CQRS. Таким образом, он обрабатывает командные сообщения и проверяет, может ли данная операция (чтение: команда) быть выполнена. Если результатом проверки является «да», тогда вы в конечном итоге публикуете событие в жизненном цикле заданных агрегатных экземпляров.

@EventSourcingHandler аннотированные методы, которые вы можете ввести в агрегат, предназначены для «источник агрегатного экземпляра основан на его собственных событиях».

Сказав это, вы можете ожидать, что Aggregate никогда не будет обрабатывать события напрямую из любого другого источника. его собственный.

EventScheduler является таким же внешним источником событий, как и события других агрегатов при поиске. Следовательно, они будут игнорироваться для агрегата.

EventScheduler опубликует sh событие на более поздней стадии, так что оно может быть обработано компонентами обработки событий, например экземплярами Saga. Если вы хотите запланировать, что что-то должно произойти для специфицированного c агрегатного или сагового экземпляра, вы должны взглянуть на DeadlineManager.

Независимо от того, что вы ' пытаясь достичь того, что (я считаю) запускает операцию в вашем агрегате из саги, вы должны использовать командные сообщения, поскольку агрегат может обрабатывать только командные сообщения.

...