如何将actor消息限制为特定类型?

mkn*_*ssl 38 scala actor akka

Akka中,除了使用使用RPC样式编程模型的"Typed Actor"API之外,有没有办法将actor限制为特定的静态类型?

我可以在Akka中使用消息传递样式而不会在actor边界处丢弃静态类型安全吗?

例如,我想使用这样的代码:

sealed abstract class FooMessage
case object Foo extends FooMessage
case object Bar extends FooMessage

class FooActor extends Actor[FooMessage] {
  def receive = {
    case Foo => () // OK

    // Would raise a compiler error:
    // case s: String => error("Can't happen, String is not a subtype of FooMessage") 

  }
}

val fooActor = actorOf[FooActor]
fooActor ! Foo // OK

// Won't compile:
fooActor ! "Hello"
Run Code Online (Sandbox Code Playgroud)

也许人们必须扩展一些基本特征或者具有Either允许系统级消息(Exit等等)的构造.

Vik*_*ang 27

然后你必须将消息类型编码到Actor ref中,这会大大减少ActorRegistry之类的值.

此外,通过强大的机制,如"成为"(这是演员模型的基础),键入消息的价值较低.

由于当消息与当前行为不匹配时Akka不会泄漏内存,因此向"错误"的actor发送"错误"消息的风险不同.

此外,Actors本质上是动态的,所以如果你想让它们变为静态,使用TypedActor(它不是RPC,它就像常规actor那样RPC,void方法是!调用,Future返回类型是!!!和其他返回类型是基于!!)

通常的做法是声明Actor可以在Actor的伴随对象中接收哪些消息,这使得更容易知道它可以接收什么.

这有帮助吗?

  • 谢谢你的回答.您(akka团队)是否曾尝试将类型约束添加到演员的消息中,或者这从未被认为是有用的想法? (2认同)
  • 过去在列表中已经讨论过它,但我们总是在同一个地方,TypedActor用于该用例,而Actor用于完全动态行为.如果你想要感受更多的控制,你可以在ActorRef之上尝试自己的抽象.这有帮助吗?干杯,√ (2认同)

Vas*_*iuk 23

在Scala stdlib中有一个借口让基本的actor无类型化(这不适用于Akka,因为它不支持嵌套的接收,我记得).反过来,提升支持开箱即用的打字演员.

但是,使用通道,仍然可以使用stdlib创建强类型的actor:

object TypedActor {

  def apply[A](fun: PartialFunction[A, Any]): OutputChannel[A] = {
    val sink = new SyncVar[Channel[A]]
    actor {
      val in = new Channel[A](self)
      sink set in
      loop {
        in react { case any => reply(fun(any)) }
      }
    }
    sink.get
  }

}

sealed abstract class FooMessage
case object Foo extends FooMessage
case object Bar extends FooMessage

object Test {

  val fooActor = TypedActor[FooMessage]{
    case Foo => println("OK")
  }

  fooActor ! Foo 
  fooActor ! "Hello!" // doesn't compile -> Type mismatch; found: String("Hello!"); required: FooMessage;

}
Run Code Online (Sandbox Code Playgroud)