scala - sender() 导致 deadLetters 用于实现但不在单元测试中
问题描述
我正在使用 Akka 经典演员(在 Play 框架中运行)并且遇到了该sender()
方法的问题。当我构建并运行代码(使用sbt run
)时,我可以看到它sender()
解析为deadLetters
actor。但是,在为该参与者运行单元测试时,会sender()
解析为正确的 ActorRef(即使它不应该)。
正在从关闭的sender()
未来中调用,这就是为什么我deadLetters
在运行实际实现时看到的原因。但是,由于某种原因,我没有deadLetters
在单元测试中看到 。为什么单元测试和运行实例之间存在行为差异的任何想法?
一些示例代码以了解代码结构
class MyActor extends Actor {
private def throwError() = {
// THIS IS WHERE sender() BEHAVIOR DIFFERENTIATES BETWEEN IMPLEMENTATION AND UNITTESTS
sender() ! MyErrorMessage()
throw new Exception()
}
private def myFutureMethod(args: SomeType): Future[Done] = {
for {
Some logic here...
} yield {
if (some logic check...)
throwError()
else
Done
}
}
override def stepReceive = {
case MyMessage(args) =>
myFutureMethod(args)
}
}
一些示例代码可以让您了解 unittest 结构
"My failure test case" in {
val testProbe = TestProbe()
myActorImpl.tell(MyMessage(args), testProbe)
// testProbe SHOULD BE NOT BE RECEIVING A MESSAGE BASED ON THE ABOVE
// IMPLEMENTATION, BUT IT DOES.
testProbe.expectNoMessage()
}
如果有人对调试有一些技巧或想法,那就太棒了。谢谢。
解决方案
调用sender
作为参与者的一部分执行的代码Future
是不确定的(即竞争条件),因为您MyActor
可以在Future
执行中的代码之前继续处理另一条消息,如果从那时起它已经sender
改变,可能到deadLetters
.
在你的测试中,如果myActorImpl
还没有处理过消息,sender
仍然会指向测试探针。
假设您希望将消息实际发送给发件人,您需要先捕获它,然后再将其交给Future
,按照这些思路
class MyActor extends Actor {
private def throwError(target: ActorRef) = {
// uses the captured sender, no race condition
target ! MyErrorMessage()
throw new Exception()
}
private def myFutureMethod(args: SomeType, sender: ActorRef): Future[Done] = {
for {
Some logic here...
} yield {
if (some logic check...)
throwError(sender)
else
Done
}
}
override def stepReceive = {
case MyMessage(args) =>
myFutureMethod(args, sender) // captures the sender reference
}
}
推荐阅读
- reactjs - 如何推入与我传递给 api 的主体相对应的数组?
- scala - 我想运行一个 scala 文件并期望输出
- r - 矩阵上的下标数不正确。同时将数据帧中的值分配给矩阵
- swift - 禁用 ObservableObject 中 @Published 变量的发送事件
- java - 每次 Oracle 发布更新时,我是否需要更新 JAVA JDK?
- c# - Winforms 标签页上的关闭按钮
- azure-logic-apps - 如何在逻辑应用程序中创建和格式化 HTML 表格
- python - 如何在 AWS CDK 中使用 IRole
- c# - 如何在 C# 网页中每天创建一个日志文件以记录信息?
- json - 在查询生成器中计算 JSON 数组