【问题标题】:Scala Akka actors - getting the state of an actorScala Akka 演员 - 获取演员的状态
【发布时间】:2019-04-23 08:58:41
【问题描述】:

receive 方法定义了 Akka Actor 中的 Actor 行为。我正在寻找一种方法,它可以为我提供演员可以在运行时在 Scala 中更好地处理的所有不同消息(及其类型)。

【问题讨论】:

  • 这是不可能的。如果你需要这样的保证,你可能想看看 akka-typed。
  • Akka typed 无法给出能够处理的消息的“类型”。 Scala 不是依赖类型语言,所以类型不是一等的。但是,Akka 类型 can 强制只有某些消息才能由某个“actor”处理。
  • 不,没有。 receive 方法被传递一个PartialFunction[Any, Unit]。在 akka typed 中,您必须指定可以处理的消息类型。
  • 还要注意,通过使用context.become,演员可以动态地改变其行为(如果演员没有context.becomed,receive 方法只是默认的)。跨度>
  • 运行中的actor的行为被存储为一个私有字段(ActorCell中的behaviorStack)。如果您可以访问该字段,则可以直接获取当前行为,即PartialFunction[Any, Unit]。从那里,您可以将消息传递给isDefinedAt 方法。这将做的最多的是让你有一个演员在那个时刻可以处理的消息列表,这不是你想要的,但这没关系,因为除非有一个主要的 JVM 漏洞利用,你是不会访问该私有字段。

标签: scala akka actor


【解决方案1】:

直接回答

很遗憾,akka 不提供您要求的功能。 receive 方法is defined as

type Receive = PartialFunction[Any, Unit]

abstract def receive : Actor.Receive

PartialFunction 无法枚举它可以处理的所有类型。此外,一旦将Actor 实例化为ActorRef,您就无法访问底层的receive 方法。

另一种方法是在Actor 实现之外定义您的接收,然后使用isDefinedAt method of PartialFunction 测试特定值:

object MyActor {
  val myPartial : Receive = {
    //receive functionality
  }
}

class MyActor extends Actor {
  override def receive : Receive = MyActor.myPartial
}

//test if a value can be processed by MyActor

val testValue = 42

val testValueIsDefined = MyActor.myPartial.isDefinedAt(testValue)

间接回答

如果你正确地组织你的代码,那么你的问题的基础就变得没有必要了。

我发现一个好的做法是严格声明 Actor 可以接收哪些类型的输入:

sealed trait MyActorInputs

case class Foo(value : Int) extends MyActorInputs
case class Bar(value : String) extends MyActorInputs

object MyActor {
  val processInput : MyActorInput => Unit = ???
}

class MyActor extends Actor {
  override def receive : Receive = {
    case input : MyActorInput => 
      MyActor.processInput(input)
    case unknown => 
      System.error.println(s"MyActor received unknown input: $unknown")
  }
}

此技术不提供编译器时间检查或严格保证,但如果您在所有 Actor 中采用它,那么它往往会使大型项目的工作更轻松。它还允许您use reflection to dynamically get a list of available input types

【讨论】:

  • 您的回答证实了确实不可能反映偏函数(接收)的类型。你进一步提供了关于我将如何编写一个我可以反思的演员程序的见解。这是方便的信息。但是,我打算扩大 Akka Scala 测试。这些将是其他开发人员编写的参与者。开发人员还将编写手动测试,我试图自动放大这些测试。为了放大手动编写的测试,我需要访问参与者处理的消息类型。你已经证明它在动态上是不可能的。所以我转向静态分析
  • 还要注意,仅仅因为PartialFunction[X, Y] 并不能保证处理任何X 它已经给出。
猜你喜欢
  • 1970-01-01
  • 2014-06-13
  • 1970-01-01
  • 1970-01-01
  • 2018-05-23
  • 2013-11-22
  • 1970-01-01
  • 2011-11-17
  • 1970-01-01
相关资源
最近更新 更多