Akka 经典与 Akka 类型化

f4x*_*f4x 3 scala akka

现在我正在学习 Akka。但是我发现 Akka 有两个版本:Classic 和 Typed。它和我应该学习的东西有什么区别?

类型化版本是否具有更强的类型控制?如果是,为什么只在 2.6 版本中引入?

谢谢回答。

Mat*_*zok 7

“经典”演员是无类型的。您定义一个接受Any对象的参与者,并使用模式匹配来定义它将实际处理哪些消息。

// from https://doc.akka.io/docs/akka/current/actors.html
class MyActor extends Actor {
  val log = Logging(context.system, this)

  def receive = {
    case "test" => log.info("received test")
    case _      => log.info("received unknown message")
  }
}
Run Code Online (Sandbox Code Playgroud)

receive您必须为每个演员定义的是PartialFunction[Any, Unit]. 它不会阻止您将消息发送给错误的参与者 - 一个会默默忽略它的参与者。它不会阻止您发送错误类型的消息。您可以将所有内容发送给所有人。

从某个角度来看,您有一个并发模型——建立在强类型语言之上——它与 JavaScript 一样强类型。

Akka Typed 所做的是,它让您通过围绕无类型角色的类型包装器发送消息:

// from https://doc.akka.io/docs/akka/current/typed/actors.html#akka-actors
object HelloWorld {
  final case class Greet(whom: String, replyTo: ActorRef[Greeted])
  final case class Greeted(whom: String, from: ActorRef[Greet])

  def apply(): Behavior[Greet] = Behaviors.receive { (context, message) =>
    context.log.info("Hello {}!", message.whom)
    message.replyTo ! Greeted(message.whom, context.self)
    Behaviors.same
  }
}

object HelloWorldBot {

  def apply(max: Int): Behavior[HelloWorld.Greeted] = {
    bot(0, max)
  }

  private def bot(greetingCounter: Int, max: Int): Behavior[HelloWorld.Greeted] =
    Behaviors.receive { (context, message) =>
      val n = greetingCounter + 1
      context.log.info2("Greeting {} for {}", n, message.whom)
      if (n == max) {
        Behaviors.stopped
      } else {
        message.from ! HelloWorld.Greet(message.whom, context.self)
        bot(n, max)
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样你有:

  • 类型的 actor ( Behavior) 告诉你他们接受什么样的消息
  • 键入ActorRef这将帮助您仅向演员发送正确类型的消息
  • typedActorSystem定义了可以直接发送到actor系统的消息类型。

它是“最近”才推出的,但它的工作持续了几年,直到最近代码才达到其创建者所期望的成熟度。该模块在 repo 中存在至少 2 年,但我记得它的工作已经持续了一段时间。第一个标记为 Akka Typed 的问题是从2017 年 5 月开始的,但任何“类型化演员”的工作都可以追溯到2014 年 5 月(这意味着作者不得不谈论它一段时间,尽管这些早期的概念是与我们今天所拥有的略有不同)。

长话短说 - 打字(对大多数人来说,大部分时间,YMMV)更好,但需要时间才能正确。如果您想在新建项目中使用它们(出于某种原因必须使用演员),那么我建议使用 Typed。如果您必须使用 Actors 在现有项目中工作,那么他们几乎肯定会使用经典,因此如果您想通过 Akka 谋生,您必须了解两者。