Первый взгляд на Akka 2.0

Через несколько месяцев выходит major-релиз Akka. Виктор Клэнг, и компания, готовят нам большой сюрприз, к которому надо начинать готовиться уже сейчас.

Те, кто с Akka уже давно (больше года), помнят сложности с миграцией, при переходе с версии 0.6 на 0.7, и, далее, на 0.8 (когда была введена концепция ActorRef, призванная отделить API актера от реализации (обрабатывающей), и, таким образом, сделать актеры более близкими к их прообразу в Erlang). Готовьтесь, друзья - изменения в Akka 2.0 носят характер революции.

Итак, по порядку:

  1. В Akka 2.0 больше нет такой концепции (по крайней мере, в рамках API), как Remote Actor и Remote Server (к слову, модуль akka-remote теперь тоже не существует). На смену им пришли кластеризованные актеры (ClusterActorRef) и кластера (Cluster и Node a la node’ы в Erlang). По умолчанию, если узел, на котором запускается актер, является частью кластера, он автоматически реплицируется на все другие узлы кластера (это происходит в рамках нового, управляемого процесса deployment’a). Когда вы отправляете кластеризованному актеру сообщение, роутер определяет, какому физическому актеру в рамках кластера будет перенаправлено сообщение (к примеру, если на “домашнем” узле памяти остается слишком мало, сообщение будет отправлено на ближайший удаленный узел). Таким образом, основная схема работы с кластеризованными актерами, на сегодняшний день, предполагает работу в духе computation grid (когда все актеры равны, обладают одинаковыми данными, и любой из них может быть выбран для вычислений);
    • По умолчанию, сообщение будет обработано только одним актером из кластера. Кроме этого, вы можете послать broadcast сообщение, которое будет доставлено всем актерам. На данный момент (по непонятным причинам) для массовой рассылки поддерживается только режим fire-forget(метод "!") - получения future’a ответа пока не поддерживается;
    • В API (пока) нет простого способа работы с конкретными актерами на удаленных узлах. Если, к примеру, у вас есть распределенный кэш (одна уникальная часть на каждом узле/JVM), и вы хотите работать с ним с помощью актеров, очевидного способа обратиться к конкретному актеру нет (вообще, складывается впечатление, что кластеризованными актерами пока хорошо поддерживается только работы в режиме реплицированных данных);
    • Есть базовая поддержка работы с кластером (базируется на Apache ZooKeeper) - вы можете отслеживать, когда в кластере появляются новые узлы и инициализируются реплики актера, устанавливать “барьеры” (что-то вроде распределенной версии CountDownLatch) и мн. другое;
    • Хотя это и не является непосредственной частью Akka 2.0, появился очень удобный плагин для sbt, позволяющий тестировать распределенные системы (кластера) на одной машине, запуская “форки” JVM, исполняя на них тесты, и собирая логи. По умолчанию плагин поддерживает только scalatest, но есть сторонний "форк" с поддержкой specs2;
  2. На смену концепциям ID и UUID , пришла более очевидная концепция адреса актера (address) и уникального идентификатора в рамках кластера;
  3. Достаточно сильно изменился API реестра актеров (ActorRegistry). Актера теперь модно получить только по адресу или уникальному идентификатору (ранее актера можно было также получить по типу);
  4. Supervisor больше не стартует актеров, за которыми он наблюдает, и не останавливает актеров, когда прекращает работу сам. Теперь пользователь сам должен стартовать всех актеров, и передавать supervisor’у инициированные объекты;
  5. Больше нет блокирующего способа обращения к актеру с помощью метода “!!”. В Akka 2.0 актеру можно посать one-way сообщение (метод “!”) или получить Future ответа (метод “?”, аналог прошлого “!!!”). Работа с Future, к слову, самая удобная (и идиоматичная, с точки зрения функционального программирования) среди всех существующих библиотек;
  6. Многие методы переименованы в соответствие с Scala Style Guide’ом (в частности, популярный метод ActorRef#reply_? переименован в ActorRef#tryReply);

Это далеко не полный список изменений - только те, что сразу бросаются в глаза (когда проект отказывается компилироваться, при переходе на новые версии библиотек). Многие вещи, которые раньше необходимо было ush реализовывать самому (поддержка node’ов и кластеров, по аналогии с Erlang/OTP), теперь входит в стандартную поставку. Умное распределение работы по однотипным актерам в рамках кластера также значительно упрощает работу (хотя, идеологически, достаточно сильно отличается от предыдущего решения). Таким образом, если вы начинаете проект на Akka 2.0 с нуля, вам придется делать намного меньше черновой работы. Если же вы мигрируете большой существующий проект с Akka 1.x, процесс может быть достаточно сложным, т.к. изменения в версии 2.0 носят не количественный характер, а концептуальный (вам, скорее всего, придется отказаться о своих решений в пользу аналогичных, входящих в Akka, и переписать ощутимое количество кода). Поэтому, всем, кто использует Akka очень советую не откладывать знакомство с новей версией фреймворка, и уже сейчас поэкспериментировать с 2.0-SNAPSHOT на одном из хобби-проектов.