Як реалізувати менеджер процесів у пошуку подій


14

Я працюю над невеликим прикладом програми, щоб вивчити концепції CQRS та пошуку подій. У мене є Basketагрегат і Productагрегат, який повинен працювати незалежно.

Ось декілька псевдокодів, щоб показати реалізацію

Basket { BasketId; OrderLines; Address; }

// basket events
BasketCreated { BasketId; }
ItemAdded { BasketId; ProductId; Quantity }
AddItemSucceeded { BasketId; ProductId; Quantity }
AddItemRevoked { BasketId; ProductId; Quantity }
ItemRemoved { BasketId; ProductId; Quantity }
CheckedOut { BasketId; Address }

Product { ProductId; Name; Price; }

// product events
ProductReserved { ProductId; Quantity }
ProductReservationFailed { ProductId; Quantity }
ProductReservationCancelled { ProductId; Quantity; }

Команди досить схожі на події, використовуючи імперативну назву і не минулий час.

Зараз вони працюють добре незалежно. Я видаю команду AddItem, і вона створює ItemAddedподію на Basketсукупності, яка робить те, що потрібно робити зі станом "кошика". Так само для продукту команда та події працюють просто чудово.

Зараз я хотів би об'єднати це в процес, який би йшов приблизно так (з точки зору команд та подій, що трапляються):

Менеджер процесів зробив би наступне:

on BasketCreated: CreateShoppingProcess
on ItemAdded: ReserveProduct
on ProductReserved: SucceedAddingItem // does nothing, but needs to be there so that the basket knows it can check out
on ProductReservationFailed: RevokeAddItem
on RemoveItem: CancelProductReservation
on Checkout: CreateOrder // create an order and so on...

Питання, на які я не зміг знайти остаточних відповідей, це:

  1. Чи потрібно наполегливо керувати процесом? Здається, як я, але я не впевнений
  2. Якщо це зробити, мені потрібно зберегти події для менеджера процесів. Однак події, які він слухає, прив'язані до сукупностей. Додавати ідентифікатор процесу до них? Чи є у мене окремі події лише для менеджера процесів? Як це зробити і зберегти як можна ДРУГІ
  3. Як я можу знати, для якого кошику проводяться ProductReservedподії? Чи добре це мати і BasketIdна них, чи це теча інформація?
  4. Як я можу підтримувати взаємозв'язок між подіями, як я можу знати, яка ItemAddedподіяла яка ProductReservedподія? Я проходжу уздовж EventId? Це здається дивним ...
  5. Чи повинен я реалізувати Basketяк менеджер процесів замість простого агрегату?

Після ще кількох досліджень я прийшов до цього: Сага - це те, що зберігає власні події та слухає події ззовні. В основному це агрегат, який також може реагувати на події, що відбуваються поза його власним маленьким світом.

Менеджер процесів працює з подіями ззовні та надсилає команди. Його історію можна відновити з подій, що відбулися на агрегатах, які мають спільний ідентифікатор, наприклад, кореляційний ід.


Здається, ви намагаєтеся кодувати у вашій системі формальний процес, який перефразовує існуючий неформальний випадок використання, складений із серії команд. У цьому випадку, схоже, ви створюєте ряд зайвих команд та подій, окрім існуючих. Це ваш намір? Що потрібно бізнесу формалізувати як процес в коді? Що у вашому домені вимагає, щоб ви визначили цей процес та обґрунтували його як повноцінне поняття?
guillaume31

Це повністю складений проект, де мета - навчитися змушувати працювати дві відносно незалежні агрегати. Тож справді немає «ділової потреби», і я намагаюся максимально уникати надмірностей у цих командах та подіях. Звідси плутанина з диспетчером процесів, тому що, здається, не слід повторювати матеріал, який агрегати вже обробляють. Однак мені потрібно якось підтримувати зв’язок між цими двома агрегатами. Здається, використання причинно-наслідкових зв’язків та кореляції може допомогти, але мені потрібно спробувати це.
Іван Пінтар

Відповіді:


14

Перегляньте, що написав Рінат Абдуллін про розвиваються бізнес-процеси . Зокрема, зауважте його рекомендації щодо розвитку бізнес-процесів у швидко мінливому середовищі - менеджер процесів є "просто" автоматизованою заміною для людини, яка дивиться на екран.

Моя власна ментальна модель менеджера процесів полягає в тому, що це проекція, що базується на події, і ви можете запитувати список команд, що очікують на розгляд.

Чи потрібно наполегливо керувати процесом? Здається, як я, але я не впевнений

Це модель для читання. Ви можете перебудовувати менеджер процесів з історії подій кожного разу, коли вам це потрібно; або ви можете ставитися до цього як до знімка, який ви оновлюєте.

Якщо це зробити, мені потрібно зберегти події для менеджера процесів.

Ні - менеджер процесів - менеджер . Він не робить нічого корисного самостійно; натомість він говорить агрегатам виконувати роботу (тобто вносити зміни до книги записів).

Як я можу дізнатися, для чого призначені події ProductReserved? Чи добре мати BasketId на них теж, або це така інформація, що протікає

Звичайно. Примітка: у більшості "справжніх" торгових доменів ви не наполягатимете на резервування запасів перед обробкою замовлення; це додає зайвої суперечки бізнесу. Більш імовірно, що ваш бізнес захоче прийняти замовлення, тоді вибачтесь у рідкісному випадку, що замовлення не може бути виконано в потрібний час.

Як я можу підтримувати взаємозв'язок між подіями, як дізнатись, який продукт додав, який продукт зарезервував продукт?

Повідомлення містять метадані - зокрема, ви можете включити причинний ідентифікатор (щоб ви могли визначити, які команди виробляли події) та кореляційний ідентифікатор , щоб загалом відстежувати розмову.

Наприклад, менеджер процесів записує власний ідентифікатор як кореляційнийId в команді; події, створені копією ідентифікатора кореляції команди, а ваш менеджер процесів підписується на всі події, у яких є власний кореляційний ідентифікатор.

Чи потрібно реалізувати Basket як менеджер процесів замість простого агрегату?

Моя рекомендація - ні. Але Уді Дахан має іншу думку, яку слід переглянути; що означає, що CQRS має сенс лише якщо ваші сукупності саги - Udi використовував сагу в тому місці, де менеджер процесів став домінуючим написанням.

чи повинні менеджери процесів отримувати агрегати?

Не зовсім? Менеджери процесів передусім стосуються оркестрації, а не стану домену. Екземпляр процесу матиме "стан" у формі історії всіх подій, які вони спостерігали - правильна річ у відповідь на подію Z залежить від того, чи ми бачили події X і Y Отже, можливо, вам потрібно буде вміти зберігати та завантажувати уявлення про цей стан (який може бути чимось рівним, або може бути історією спостережуваних подій).

(Я кажу "не дуже", тому що сукупність визначена досить невиразно, що не зовсім неправильно стверджувати, що список спостережуваних подій є "сукупністю". Відмінності є більш семантичними, ніж реалізація - ми завантажуємо стан процесу, а потім вирішуємо, до яких повідомлень відправити до частин системи, відповідальної за стан домену . Тут відбувається трохи розмахування рукою.)

Тож прем'єр-міністру не потрібно використовувати один тип управління державою над іншим, оскільки він несе відповідальність лише за те, щоб робити речі в прямому ефірі і ніколи під час повторів?

Не зовсім - державне управління - це не те, що це робити, це відслідковувати його. У тих випадках, коли керований процесом не повинен випромінювати жодних сигналів, ви надаєте йому інертні зв’язки зі світом. Іншими словами, dispatch(command)це не-оп.


1
Ви кажете: Ви можете перебудовувати менеджер процесів з історії подій кожного разу, коли вам це потрібно ... Але щоб відновити його, мені потрібно зберегти для нього події. Або я повинен будувати це з подій у сукупності? Частина, з якою я боюся, полягає в тому, що з агрегатами події мають сукупний ідентифікатор, і його легко відновити, знайти всі події з цим сукупним ідентифікатором. Але як би я це зробив для менеджера процесів? Чи потрібно це робити менеджеру процесів? Або менеджер процесів повинен шукати сукупності, коли йому потрібно щось вирішити, виходячи з події, яка відбулася?
Іван Пінтар

Чого мені не вистачало, це поняття причинно-наслідкової зв’язки та кореляції в пошуку подій. Як тільки я це задумав, то ваша відповідь на четверте питання нарешті мала сенс.
Іван Пінтар

1
Я хотів би відповісти на перший коментар @IvanPintar; чи повинні менеджери процесів отримувати агрегати? Чи повинні вони будувати свої власні на основі подій, які він обробляє? У такому випадку обробникам подій потрібно було б бути без побічних ефектів, правда?
Джефф

@Jeff В одному прикладі, який я робив у менеджера процесів, було власне сховище, яке оновлювалося з кожною оброблюваною подією, якась модель читання. Це було просто зробити, і було легко відстежити, що він уже обробив. В іншому прикладі менеджер процесів створив і зберігав власні події, побудовані за допомогою сукупних подій. Подібно до вище, але держава спричиняла події. Залежно від складності стану, який зберігає менеджер процесів, може бути простіше зробити те чи інше. Я знайшов перший підхід простішим.
Іван Пінтар

Цікаво, тож це більш-менш залежить від розробника, поки менеджер процесів реагує на події та розсилає команди зрештою?
Джефф

2

Те, що ви шукаєте, має шаблон під назвою "Сага", який по суті є менеджером процесів.

Саги також ідеально підходять для тривалих процесів, оскільки вони можуть підтримувати стан між корельованими командами.

Ось чудова стаття про Саги

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.