2016-07-15 3 views
4

Я работаю над образцом проекта Fabric, где мне нужно вести список покупок. Для этого у меня есть актер ShoppingList, который идентифицируется определенным идентификатором. Он сохраняет содержимое текущего списка в своем состоянии, используя StateManager. Все работает нормально.Сервис Ткань Актеры - сохранить состояние в базе данных

Однако параллельно я хотел бы сохранить содержимое списка покупок в базе данных sql. В частности:

  • магазин все добавить/удалить запрос элемента для будущего анализа (ML)
  • на первой инициализации актер списка загрузки контента из БД (например, после того, как кластер был создан заново)

Каков наилучший подход для достижения этого? Создайте пользовательский StateProvider (как? Не можете найти примеры)? Возможно, у вас есть другой сервис/актер для обработки всех операций db (возможно, с использованием очередей и напоминаний)?

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

ответ

5

Лучшим способом будет иметь отдельный объект, ответственный за хранение данных в БД. И актер просто отправит событие (не подразумевая SF-события) с некоторыми данными о выполненной операции, а другой объект поймает его и выполнит оставшуюся часть работы.

Но, конечно, вы можете реализовать эту вещь в себе актера, но он принесет две возможные проблемы:

  • актер будет не в состоянии обрабатывать другие запросы, если будут какие-то проблемы с БД или связи между актера и БД, или если будет большая загрузка самой БД, и она будет обрабатывать запросы медленно. Актеру придется подождать, пока передача в БД завершится успешно.
  • Возможная перегрузка БД со многими отдельными соединениями от многих участников вместо одного или нескольких соединений от другого объекта и пакетная вставка.

Итак, ваше окончательное решение будет зависеть от рабочей нагрузки вашей системы. Но определенно вам понадобится надежная очередь для безопасного хранения данных в БД, если значение таких данных слишком велико, чтобы позволить себе потерю.

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

И еще одно, что нужно учитывать - чтение из БД. Вероятно, если у вас есть база данных отношений и будет обновляться новыми записями только одна таблица +, если будет огромное количество участников, которые будут запрашивать такие данные при активации, у вас будет ухудшение производительности, поскольку эта таблица будет заблокирована для чтения или записи, если вы не будет настраивать его на поведение по-разному. Таким образом, возможно, вам понадобится система кэширования для чтения данных для активации актеров - зависит от вашей рабочей нагрузки.

И о внедрении пользовательского государственного менеджера: посмотрите пример this. В принципе, все, что вам нужно сделать, это реализовать интерфейс IReliableStateManagerReplica и передать его в конструктор StatefullService.