Сложная работа агрегат
У меня очень сложный рабочий процесс, и я не на 100% понимаю, с чем и как справиться. Я не хочу иметь код, это просто вопрос, кто за что отвечает.
Дано следующее:
- Существует корневой каталог "C:\server"
- Внутри две директории "ftp" и "backup"
Представьте себе следующий процесс:
- Внешний клиент отправляет файл в каталог ftp.
- Приложение для импорта получает файл, и теперь начинается самое интересное.
- Для этого файла необходимо создать агрегат заданий.
- Команда "CreateJob(строковый файл)" запускается.?. Файл должен быть перемещен из ftp в резервную копию. Внутри CommandHandler или внутри события Aggregate или JobCreated?
- StartJob (Guid jobId) get называется. Третья папка должна быть создана "в процессе", файл должен быть скопирован из резервной копии в процессе. Кто это делает?
Поэтому для меня неясно, где вещи с файловой системой должны обрабатываться, если агрегат не может работать правильно без правильной файловой системы. Потому что мой первый подход состоял в том, чтобы сделать это на уровне инфраструктуры /lib, который прослушивает события из уровня работы. Но, похоже, не на 100% правильно?!
И в довершение всего, что с воспроизведением? Вы не можете воспроизвести вещи / файлы, которые были перемещены, вы должны каким-то образом симулировать, что клиент отправляет файл в папку ftp...
Благодарен за ответы
2 ответа
Файл должен быть перемещен из ftp в резервную копию. Внутри CommandHandler или внутри события Aggregate или JobCreated?
В подобных ситуациях я перемещаю файл в папку назначения в Application
служба, которая отправляет команду Aggregate
(или это вызывает подобный команде метод на Aggregate
, то же самое), прежде чем команда отправляется Aggregate
, Таким образом, если есть какие-то проблемы с файловой системой (недостаточно прав или недостаточно места и т. Д.), Команда не отправляется. Такого рода проблемы не должны доходить до наших Aggregate
, Мы больше всего защищаем его от инфраструктуры. На самом деле мы должны сохранить Aggregate
изолированы от всего остального; он должен содержать только чистую бизнес-логику, которая используется для определения того, какие события генерируются.
Потому что мой первый подход состоял в том, чтобы сделать это на уровне инфраструктуры /lib, который прослушивает события из уровня работы. Но, похоже, не на 100% правильно?!
На самом деле, это кажется мне слишком сложным. Вы должны поцеловать.
StartJob (Guid jobId) get называется. Третья папка должна быть создана "в процессе", файл должен быть скопирован из резервной копии в процессе. Кто это делает?
Тот, кто зовет StartJob
мог сделать переезд, прежде чем StartJob
вызывается. Снова, держите Aggregate
чистый. В этом случае это зависит от вашей структуры / деталей домена.
И в довершение всего, что с воспроизведением? Вы не можете воспроизвести вещи / файлы, которые были перемещены, вы должны каким-то образом смоделировать, что клиент отправляет файл в папку ftp...
События загружаются из хранилища событий и воспроизводятся в двух ситуациях:
Перед отправкой каждой команды
Aggregate
,Aggregate Repository
загружает все события из хранилища событий, а затем применяет каждое из них кAggregate
, вероятно, зовет некоторыхapplyThisEvent(TheEvent)
метод по совокупности. Таким образом, эти методы должны быть без побочных эффектов (чистыми), иначе вы меняете внешний мир снова и снова при каждом выполнении команды, и вам это не нужно.read-models
(projections
,query-models
) которые представляют данные пользователю, прослушивают эти события и обновляют таблицы базы данных, в которых хранятся данные, которые видят пользователи. События отправляются этим моделям чтения после того, как они сгенерированы, и каждый раз, когда модели чтения воссоздаются. Когда вы изобретаете новыйread-model
, вы должны передать все события, которые были ранее сгенерированыaggregates
чтобы построить правильное / полное состояние на них. Если у слушателей событий модели чтения есть побочные эффекты, что, по вашему мнению, происходит, когда вы воспроизводите эти давно прошедшие события? Внешний мир изменяется снова и снова, и вы этого не хотите! Модели чтения только интерпретируют события, они не генерируют другие события и не изменяют внешний мир.
Существует особый третий случай, когда события достигают другого типа модели: Saga
, Saga
должен получить событие только один раз! Это тот случай, когда вы решили использовать Because my first approach was to do that inside an Infrastructure layer/lib which listen to the events from the job layer
, Вы могли бы сделать это в вашем случае, но это не KISS.
У меня очень сложный рабочий процесс, и я не на 100% понимаю, с чем и как справиться. Я не хочу иметь код, это просто вопрос, кто за что отвечает.
Обычный ответ заключается в том, что модель предметной области, то есть "совокупность", принимает решения и сохраняет их. Наблюдая за этими решениями, некоторые обработчики событий вызывают побочные эффекты.
И в довершение всего, что с воспроизведением? Вы не можете воспроизвести вещи / файлы, которые были перемещены, вы должны каким-то образом смоделировать, что клиент отправляет файл в папку ftp...
Вы воспроизводите события в агрегат, чтобы он был восстановлен до состояния, в котором он принял последнее решение. Это отдельная задача от воспроизведения побочных эффектов - что является частью мотивации для обработки побочных эффектов в другом месте.
Конечно, по возможности, вы предпочитаете, чтобы побочные эффекты были идемпотентными, чтобы дублированное сообщение не создавало проблемы. Но обратите внимание, что с точки зрения модели на самом деле не имеет значения, будет ли побочный эффект успешным или нет.