Scala Akka演员-获得演员的状态
Scala Akka演员-获得演员的状态,scala,akka,actor,Scala,Akka,Actor,receive方法在Akka actors中定义了一个actor的行为。我正在寻找一种方法,它可以为我提供参与者在Scala中运行时最好能处理的所有不同消息(及其类型) 直接回答 不幸的是,akka无法提供您所要求的功能。receive方法: PartialFunction无法枚举它可以处理的所有类型。此外,一旦Actor被实例化为ActorRef,您就无法访问底层的receive方法 另一种方法是在Actor实现之外定义接收,然后使用测试特定值: object MyActor { val
receive
方法在Akka actors中定义了一个actor的行为。我正在寻找一种方法,它可以为我提供参与者在Scala中运行时最好能处理的所有不同消息(及其类型) 直接回答
不幸的是,akka
无法提供您所要求的功能。receive
方法:
PartialFunction
无法枚举它可以处理的所有类型。此外,一旦Actor
被实例化为ActorRef
,您就无法访问底层的receive
方法
另一种方法是在Actor
实现之外定义接收,然后使用测试特定值:
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)
间接回答
<>如果你正确地组织你的代码,那么你的问题的基础就变得不必要了。
我发现一个很好的做法是严格声明演员可以接收哪些类型的输入:
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")
}
}
这种技术不提供编译器时间检查或严格的保证,但是如果您在所有参与者中都采用这种技术,那么对于更大的项目来说,它会使工作更轻松。它还允许您执行。这是不可能的。如果需要这样的保证,您可能需要查看akka类型。akka类型无法提供能够处理的消息的“类型”。Scala不是依赖类型的语言,因此类型不是一流的。Akka-typed可以强制执行只有特定的消息才能由特定的“参与者”处理。不,没有。
receive
方法被传递一个PartialFunction[Any,Unit]
。在akka typed中,您必须指定可以处理的消息类型。还要注意,通过使用context.been
,参与者可以动态更改其行为(如果参与者没有context.been
d,则receive
方法只是默认方法)。正在运行的参与者的行为存储为私有字段(ActorCell
中的behaviorStack
)。如果可以访问该字段,则可以获取其头部以获取当前行为,这是一个部分函数[Any,Unit]
。从中,您可以将消息传递到isDefinedAt
方法。这样做的最大好处是让您有一个参与者可以及时处理的消息列表,这并不是您想要的,但这没关系,因为除非有重大JVM攻击,您将无法访问该私有字段。您的回答证实,确实无法反映部分函数(receive)的类型。你进一步给出了我将如何编写一个演员程序的见解,我可以对此进行反思。这是方便的信息。然而,我打算放大Akka Scala测试。这些测试将由其他开发人员编程。开发人员还将编写手动测试,我试图自动放大这些测试。为了放大手工编写的测试,我需要访问参与者处理的消息类型。你已经证明了这是不可能的。所以我转向静态分析,注意,仅仅因为一个PartialFunction[X,Y]
并不能保证处理给定的任何X
。
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")
}
}