3

Совокупные корни для контроля изменений состояния - то, что разрешено в настоящее время, а что нет. Если переход состояния разрешен, продолжайте. Если нет, вы делаете исключение, объясняющее причину, по которой это было запрещено.Агрегат-корень: состояние Изменение или сбой при исключении или ...?

Но что если state- изменение не бывает, потому что это уже в запрашиваемом государстве?

Например, если у вас есть метод Approve для вашего заполнителя, и к тому моменту, когда он называется, состояние уже одобрено?

  • Должен ли исключение бросить а-ля "XYZ уже утвержден"?
  • Или это должно быть молча игнорируется?
  • Или следует изменить состояние «» с сообщением «0» (event-sourcing, next paragraph)?

В моем случае я использую event sourcing, поэтому происходит событие, если произошло изменение состояния. Наличие событий в моем потоке событий без реального изменения состояния не кажется мне «чистым», потому что я хотел бы быть уверенным, что события действительно были созданы из-за изменений, изменяющих состояние.

Есть эмпирическое правило?

EDIT:
В описанном случае утверждения утвержденную элемент не будет действительно больно. Так что, как правило, так (спасибо @Eben Roux, @ guillaume31).

Но давайте добавим немного больше специи к нему (фактический вопрос за вопросом):

Предположим:

  • сообщение шины
  • асинхронной команда/обработка событий
  • технолог

Что делать, если диспетчер процессов (aka saga) выдает команду (асинхронный) и хочет знать, была ли выполнена эта команда? Я думаю, что уменьшит умственную нагрузку/источники ошибок, если менеджер процессов будет не должен заботиться об этом подробности реализации.

Я вижу 3 способа обработки, что:

  • имеет «Command с идентификатором ABC удалось/не удалось» сообщение отправляется на автобус
    процесса-менеджер ожидает для этого сообщений вместо этого события
  • сделать команду выполнения синхронизации
    , если процесс-менеджер не встречает каких-либо исключений, все в порядке, переходите
  • ввести новое событие ApprovalDeclined { WasAlreadyApproved = true }
    дополнительно процесс-менеджер ожидает для этого события - склонение является частью совокупной истории, может быть преимуществом, может быть, никогда не нужно ...

Я знаю: " это зависит от «
Но можете ли вы придумать какое-либо другое (более элегантное/легкое/другое) решение? Какой ваш любимый «совместимый с процессом-менеджер» способ решения этой проблемы?

ответ

2

Я не думаю, что для этого будет эмпирическое правило.

Message idempotence - это, конечно, хорошая вещь, поэтому просто игнорирование сообщения/изменения состояния - это , вероятно, путь.

Я бы не стал повторять это снова, так как эффекта нет.

1

Я бы сказал, это зависит от вашего домена. Если вы хотите предупредить пользователя, что они одобряют уже утвержденную вещь, должна быть некоторая обратная связь от совокупности. Это может быть исключение as in Deactivate() here или возвращаемое значение, переданное обработчиком/обработкой приложения (обратите внимание, что это может быть не совместимо с CQRS на 100%).

Если факт, что утверждение уже сделано, не имеет значения для задачи домена, вы можете просто игнорировать действие или выполнить его снова независимо.

С точки зрения пользовательского интерфейса, вы, скорее всего, не позволит reapprove что-то в любом случае, так что случаи, когда это происходит будет маргинальной: одновременные утверждения на 2 пользователей, скрипты, которые делают «грубой силы» одобрение и т.д.

+0

Да, +1 для 'зависит от вашего домена (или, альтернативно, здравого смысла). –

0

Кажется - для меня - вы путаете проблемы приложений и инфраструктуры.

Уровень приложения зависит от ожидаемого поведения конкретного домена. Что будет бизнес-обоснованием для утверждения дважды? Почему это вообще произойдет? Может быть, это просто проблема параллелизма на уровне пользовательского интерфейса, но тогда почему несколько пользователей одновременно одобряют одно и то же? Может быть, проблема на уровне бизнеса еще не решена. Понимание того, почему первое необходимо. Решение часто не входит в программное обеспечение.

Уровень инфраструктуры связан с такими вещами, как гарантированная доставка сообщений (например, по крайней мере один раз или ровно один раз). Когда инфраструктура не может оправдать это обещание, как это влияет на бизнес (если есть)? Как это влияет на ваш процесс? Каков ваш процесс в любом случае? Опять же, важно рассуждать об этих вещах с точки зрения домена. В конце дня вы выполняете либо риск, либо снижение операционных издержек.

В этом конкретном случае спросите себя, почему и как ваш процесс добрался до места, где он был, прежде чем отпустить команду одобрения (немного странно для процесса одобрения, обычно это делается людьми). Как получилось, что он не соблюдал предыдущие утверждения (помните, что когда-либо агрегат был уже утвержден)? Вы можете ввести тайм-аут (как сообщение его (процессу) будущему «я»), но в этом случае кажется странным (я не знаю, что сказать достаточно).

Не принимайте это неправильно, но я думаю, вам нужно либо углубиться в предметную область, либо поделиться большей частью спецификой.

+0

Я читаю взад и вперед свой ответ, но я думаю, что это не то, что я пытаюсь выяснить, но он по-прежнему оценивается! Вопрос (эволюционированный) заключается не в доставке сообщений - это больше о том, как менеджер процессов знает, что его команда преуспела - в общем? Помимо данного случая - который был просто (может быть, и плохим) примером - я все еще пытаюсь обернуть голову вокруг того, что делать, когда я уже пришел к выводу, что мне нужно реализовать диспетчер процессов (без ESB) ... –

+0

... Это влияет на «правило», с помощью которого агрегаты имеют дело с этим изменением состояния без изменения состояния или исключением из-за отсутствия события. Либо: Отсутствие системного события CommandFailed на шине с идентификатором команды. «Не удалось», хотя агрегат находится в нужном желаемом состоянии? Кажется, неправильно. Или: Нет команды aggregate-state-change => «pass» без отправленного события-сообщения => CommandSucceeded системное событие на шине. Это будет иметь для меня наибольший смысл, хотя теперь диспетчер процессов слушает системные события, а не «обычные» события ... Я просто ищу некоторые рекомендации в этом вопросе. –