Про Effective Akka
Очень полезная книга про правильное использование модели акторов из акки. Никакого срыва покровов или фундаментальных рассуждений о выстраивании архитектуры на акторах, просто краткое описание паттернов и хороших практик, многие из которых были для меня в новинку.
Универсальный дисклеймер к текстам про акку:
Акторы как объекты
Первая концепция, которая была для меня в новинку — это инициализация нескольких акторов одного типа, как объектов в классическом ООП подходе. Я привык к модели работы, когда в системе поднимается только один актор каждого типа (за редкими исключения). Система акторов образует граф, по рёбрам которого перемещаются сообщения, а каждая вершина существует в единственном экземпляре. А в книжке напоминается, что актор занимает в куче всего 400 байт, а значит можно плодить инстансы акторов также щедро, как экземпляры обычных Scala-классов. А при проектировании распределённых систем ещё и выстраивать иерархии, в которых несколько акторов, получающих сообщения через роутер, выполняют одну задачу.
Cameo Pattern
Допустим, нам надо отправить из одного актора сообщения в три других, а все три ответа вернуть одновременно. Можно написать такой код:
Но так делать не надо, потому что при каждому вызове метода ask
создаётся временный актор, который отслеживает не истёк ли таймаут и передаёт ответ через Promise
. С точки зрения производительности это очень плохо.
Вместо этого можно создать один временный актор, который с учётом таймаута накопит в себе ответы от остальных акторов, отправит их в сообщении и умрёт. Это решение в плане производительности в несколько раз лучше цепочки вызова ask
. Исходный код с примером применения паттерна есть на гитхабе Jamie Allen. Для себя я отдельно выделил полезнейшую функцию tell
, которая подменяет отправителя сообщения.
Блокировочки
Много внимания уделено избеганию блокирующего кода. Начав с банального совета выносить продолжительные операции в Future
, автор быстро перешёл к работе с ExecutionContext
. Если вкратце, то испольнять все фьючи приложения в одном контексте плохо, потому что пул потоков не резиновый. Рекомендуется выделять отдельные контексты для мест с блокирующим IO и для различных зон ответственности (failure zones) — так в книге называются замкнутые относительно распространения ошибок части приложения.
Лучшей практикой создания контекста названо обращение к контексту, объявленному в конфиге.
А ещё я познакомился с функцией scala.concurrent.blocking
, в которую рекомендуется оборачивать блокирующий код.
Chaining Pattern
Вот хочу я, чтобы сообщения, отправляемые в несколько совершенно разных акторов сначала проходили через общую функцию receive
, в которой сообщения определённых типов обрабатывались, а остальные уже отправлялись в целевые акторы. При этом я не хочу городить иерархии с наследованием. Здесь мне на помощь приходит функция orElse
и Chaining Pattern. Осталось просто скомбинировать функции в нужном порядке, обернуть их в трейты и готово:
Push Pattern
В качестве одного из свойств реактивных приложений приводится семантика “отправь и забудь”. В модели акторов она находит следующее выражение: когда мы хотим получить что-то от другого актора, мы отправляем ему запросы до тех пор, пока он не ответит. Приводится простой паттерн, который позволяет достаточно удобно реализовать это при помощи переключения контекстов:
А если мы хотим обрабатывать больше сигналов Start одновременно, можно поднимать временные акторы, как в паттерне Cameo.
Прочие советы
Системы, построенные на акторах, должны минимально зависеть от времени. А лучше, если состояние системы вообще не зависит от времени с момента запуска. Как только время становится важным, отладка системы усложняется в разы. Ошибки начинают приводить к совершенно неожиданным последствиям. При проектировании систем надо стараться придумать способы достижения целей, не зависящие от времени, либо изолировать таймеры и шедулеры от бизнес-логики.
А ещё для простоты отладки рекомендуется добавлять к сообщениям уникальные id. Я это не пробовал, но звучит разумно.
Итог
Книга рекомендуется к прочтению всем, кто работает с акторами из Акки.