Перейти к основному содержимому

Event-driven архитектура

Назначение

WMS использует Spring Application Events для асинхронной коммуникации между компонентами. Документы и операции публикуют события, слушатели реагируют на них — распространяют изменения, запускают процессы, обновляют агрегаты.

Типы событий

В системе 103 класса событий, организованных по доменам.

Документные события

СобытиеКогда публикуетсяНазначение
BaseDocSavedEventШаг 12 конвейера (после сохранения документа)Базовое событие для всех документов
DocStatusChangedEventШаг 10 конвейера (при смене статуса)Реакция на переходы статусов
*DocSavedEventПосле сохранения конкретного типа документаТипизированные события (OrderDocSavedEvent, PickingDocSavedEvent и т.д.)

Движения и контейнеры

СобытиеКогдаНазначение
ContainerContentChangedEventПосле движений, затрагивающих контейнерыОбновление агрегатов SkuItems
StorageRegistryMovement и др.При проведении движенийМогут использоваться слушателями

SNS-события

Пакет event/sns/ — события для интеграции с внешними системами через SNS.

Паттерны использования

Каскадное обновление документов

OrderDoc сохранён → OrderDocSavedEvent
└── Слушатель обновляет OrderBatchDoc
└── OrderBatchDocSavedEvent
└── Слушатель обновляет PickingDoc

Перегенерация агрегатов

StorageRegistryMovement + ContainerMovement
→ ContainerContentChangedEvent (IDs контейнеров + min time)
→ Слушатель перегенерирует SkuItems для затронутых контейнеров

Асинхронные задачи

DocStatusChangedEvent (status = READY)
→ Слушатель запускает асинхронную обработку

Публикация событий

Документы создают события через hook createDocSavedEvent():

// В конкретном менеджере документа
@Override
protected BaseDocSavedEvent<OrderDoc, OrderStatus> createDocSavedEvent(OrderDoc doc) {
return new OrderDocSavedEvent(doc, getChangedFields());
}

Публикация может быть отключена модификатором DISABLE_PUBLISH_EVENT.

Подписка на события

Стандартный механизм Spring:

@EventListener
public void onOrderSaved(OrderDocSavedEvent event) {
// реакция на сохранение заказа
}

@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void afterOrderCommitted(OrderDocSavedEvent event) {
// после коммита транзакции
}