Что такое Akka Typed и как она отличается от классической Akka?
Akka Typed — это новая, типобезопасная версия акторной модели Akka, представленная как официальная альтернатива классическому (untyped) API. Основная цель Akka Typed — обеспечить строгую типизацию сообщений и поведения акторов, минимизируя ошибки во время компиляции и улучшая масштабируемость кода.
Отличие от классической Akka
1. Статическая типизация сообщений
В классической Akka (akka.actor.Actor) метод receive принимает любые типы сообщений (Any), и программист должен вручную проверять типы:
def receive = {
case s: String => println(s"Got a string: $s")
case n: Int => println(s"Got a number: $n")
}
В Akka Typed сообщения строго типизированы через параметр:
Behavior\[String\]
Актор, принимающий только строки, не сможет принять Int, Boolean и прочие типы — компилятор это отследит.
2. Никаких классов-наследников
В классической Akka акторы реализуются как классы, унаследованные от akka.actor.Actor.
class MyActor extends Actor {
def receive = {
...
}
}
В Akka Typed акторами управляет функция, возвращающая Behavior[T]:
val myBehavior: Behavior\[String\] = Behaviors.receive { (ctx, msg) =>
...
}
Это делает поведение более функциональным, легче читаемым и поддающимся рефакторингу.
3. Поведение как значение
В классической Akka поведение — это receive метод. В Akka Typed поведение — это значение типа Behavior[T], которое можно возвращать, передавать, сохранять.
def counter(n: Int): Behavior\[String\] =
Behaviors.receiveMessage {
case "inc" => counter(n + 1)
case "print" =>
println(n)
Behaviors.same
}
Каждое сообщение может возвращать новое поведение, и эта возможность естественным образом реализует конечные автоматы.
4. Строгая типизация контекста и акторных ссылок
Контекст (ActorContext) и акторные ссылки (ActorRef) тоже типизированы. Это гарантирует, что нельзя отправить неправильное сообщение.
def apply(): Behavior\[Command\] =
Behaviors.receive { (ctx: ActorContext\[Command\], msg: Command) =>
...
}
В классической Akka ActorRef может принимать Any.
5. Явное создание акторов через Behaviors
Вместо system.actorOf(Props(...)), в Akka Typed создаётся Behavior:
val greeter: Behavior\[Hello\] = Behaviors.receive { (ctx, msg) =>
...
}
val system: ActorSystem\[Hello\] = ActorSystem(greeter, "HelloSystem")
Тип ActorSystem[Hello] указывает, что система ожидает акторов, обрабатывающих сообщения типа Hello.
Пример: классическая Akka
case class Greet(name: String)
class Greeter extends Actor {
def receive = {
case Greet(name) => println(s"Hello, $name")
}
}
val system = ActorSystem("ClassicSystem")
val greeter = system.actorOf(Props\[Greeter\])
greeter ! Greet("Alice")
Пример: Akka Typed
case class Greet(name: String)
val greeter: Behavior\[Greet\] = Behaviors.receive { (ctx, msg) =>
println(s"Hello, ${msg.name}")
Behaviors.same
}
val system = ActorSystem(greeter, "TypedSystem")
system ! Greet("Alice")
Преимущества Akka Typed
-
Безопасность на этапе компиляции — уменьшает runtime-ошибки.
-
Явное определение контрактов акторов — легче читать и сопровождать.
-
Функциональный стиль — легче писать композиции, менять поведение.
-
Простота тестирования — поведение как чистая функция.
-
Лучшая поддержка IDE и автодополнения.
Поддержка Akka Typed и миграция
Akka Typed является предпочтительной моделью с версии Akka 2.6. Старое untyped API не удалено, но считается устаревающим. Также можно интегрировать untyped и typed акторы в одном проекте через akka.actor.typed.adapter._, но лучше придерживаться typed-подхода при разработке новых компонентов.
Поведение акторов в Akka Typed
Akka Typed предоставляет множество функций для управления поведением:
-
Behaviors.same — оставить текущее поведение.
-
Behaviors.ignore — игнорировать все сообщения.
-
Behaviors.stopped — завершить актор.
-
Behaviors.receiveMessage — упростить поведение без контекста.
-
Behaviors.setup — задать инициализацию.
Иерархия акторов и супервизия
Akka Typed поддерживает те же механизмы надзора:
Behaviors.supervise(childBehavior).onFailure\[Exception\](SupervisorStrategy.restart)
Поведение оборачивается в супервизор, который определяет, что делать в случае ошибки.
Резюме отличий (без выделения)
Особенность | Classic Akka | Akka Typed |
---|---|---|
Типизация сообщений | Нет (Any) | Есть (Behavior[T]) |
--- | --- | --- |
Акторы | Класс Actor | Функция Behavior[T] |
--- | --- | --- |
Контекст и ActorRef | Нетипизированный | Типизированный |
--- | --- | --- |
Смена поведения | context.become | Behavior[T] |
--- | --- | --- |
Безопасность | Runtime-ошибки | Компиляция ловит ошибки |
--- | --- | --- |
Интеграция с typed supervision | Сложно | Встроено |
--- | --- | --- |
Akka Typed — это более современный, надёжный и строгий способ построения масштабируемых акторных систем, особенно при создании крупных приложений, где стабильность и читаемость имеют решающее значение.