После отправки счёта процесс должен продолжиться по первому из двух событий: оплате или истечению срока. Аналитик использовал такой фрагмент BPMN. Какой элемент нужно применить вместо шлюза?
<process id="payment">
<parallelGateway id="waitForResult"/>
<intermediateCatchEvent id="paymentReceived"/>
<intermediateCatchEvent id="deadlineReached">
<timerEventDefinition/>
</intermediateCatchEvent>
</process>
Вместо parallelGateway нужен шлюз, основанный на событиях — event-based gateway. Он выбирает ветвь по первому наступившему событию: оплате или истечению срока; после выбора остальные альтернативы больше не участвуют в ожидании.
BPMN создавался как общая нотация для описания бизнес-процессов, чтобы бизнес-аналитики, владельцы процессов и технические команды одинаково трактовали поведение процесса. Для этого в нотации отдельно выразили обычное ветвление по условиям и ожидание внешнего события.
Шлюз, основанный на событиях, решает задачу, в которой заранее неизвестно, какой из взаимоисключающих триггеров произойдёт первым. Это отличается от выбора по уже известному логическому условию.
Параллельный шлюз запускает все исходящие ветви одновременно и обычно требует синхронизации последующих потоков. В данном сценарии оплата и истечение срока — альтернативные события, поэтому запуск обеих ветвей не отражает бизнес-смысл.
Если процесс ждёт оба результата, он может задержаться после оплаты до наступления таймера. Если одна из ветвей не должна завершаться никогда, процесс может остаться в незавершённом состоянии. Кроме того, параллельный шлюз не выражает правило «побеждает первое событие».
После event-based gateway размещают события, которые процесс способен поймать: например, событие получения сообщения об оплате и промежуточное таймерное событие. Процесс ожидает их одновременно, но продолжает выполнение только по ветви события, наступившего первым.
В этом фрагменте шлюз не проверяет выражение вроде статуса платежа. Он создаёт ожидание событий, а тип события определяет выбранную ветвь. После срабатывания одной альтернативы ожидание других альтернатив прекращается в рамках данного экземпляра процесса.
Такой шлюз следует применять, когда события являются альтернативными и взаимно исключающимися. Если нужно дождаться всех результатов, подходит параллельный шлюз. Если ветвь выбирается проверкой данных, а не наступлением события, следует рассматривать исключающий шлюз.
Важно заранее определить семантику пограничных случаев: что делать при почти одновременной оплате и тайм-ауте, можно ли принять позднюю оплату после закрытия заказа и требуется ли идемпотентная обработка повторного уведомления. Эти правила относятся уже к требованиям процесса, а не только к графическому обозначению шлюза.
Интернет-магазин после создания заказа отправлял счёт и должен был либо подтвердить заказ после уведомления платёжного провайдера, либо отменить его по тайм-ауту. Рассматривались три варианта: параллельный шлюз, исключающий шлюз с проверкой статуса и шлюз, основанный на событиях.
Параллельный шлюз был отклонён: он моделировал одновременное выполнение альтернатив и создавал риск ожидания двух несовместимых результатов. Исключающий шлюз также не подходил сразу после отправки счёта, поскольку в этот момент статус оплаты ещё мог быть неизвестен и требовал отдельного механизма ожидания.
Выбрали event-based gateway с сообщением об оплате и таймером. После этого оплата переводила заказ в подтверждённое состояние, а таймер — в отменённое; поздние уведомления обрабатывались отдельным правилом идемпотентности. Это устранило зависание процесса и сделало правило выбора ветви явным.
Чем event-based gateway отличается от exclusive gateway?
Исключающий шлюз выбирает исходящий поток на основании условий, вычисляемых по данным или состоянию процесса. Event-based gateway не вычисляет такие условия: он ожидает наступления событий и выбирает поток по тому, какое событие произошло первым.
Можно ли после event-based gateway разместить обычную задачу?
Непосредственно после такого шлюза обычно размещают элементы, способные ожидать или фиксировать событие: например, сообщение или таймер. Обычная задача сама по себе не является событием, поэтому её размещение может нарушить ожидаемую семантику модели или зависеть от ограничений конкретного инструмента.
Что произойдёт с поздним событием после выбора одной ветви?
Альтернативное ожидание прекращается для данного экземпляра процесса. Однако внешняя система может всё равно доставить позднее сообщение, поэтому обработчик должен корректно игнорировать его, сопоставить с уже закрытым заказом или запустить предусмотренный компенсационный сценарий. Это нужно явно зафиксировать в требованиях, иначе корректная BPMN-модель не гарантирует корректное поведение интеграции.