TestActorRef 死锁可能性是否仍然相关?
Is TestActorRef deadlock possibility still relevant?
在 akka 2.3.9 documentation 中有一个警告:
Any message send from a TestProbe
to another actor which runs on the
CallingThreadDispatcher
runs the risk of dead-lock, if that other actor
might also send to this probe. The implementation of TestProbe.watch
and
TestProbe.unwatch
will also send a message to the watchee, which means
that it is dangerous to try watching e.g. TestActorRef
from a TestProbe
.
我试图在测试中使用 TestProbe
和 TestActorRef
重现所描述的死锁情况,因为两者都使用 CallingThreadDispatcher
class DeadlockTest extends TestKit(ActorSystem()) with FunSuiteLike {
test("deadlock attempt") {
val b = TestProbe()
val a = TestActorRef(new Actor {
override def preStart() = b.ref ! "pre"
def receive = {
case msg =>
sender ! msg
context.stop(self)
}
})
b.watch(a)
b.send(a, "foo")
b.expectMsg("pre")
b.expectMsg("foo")
b.expectTerminated(a)
b.unwatch(a)
}
}
我预计测试会挂起,但它成功通过了。
警告是否仍然相关并且死锁的可能性很高还是已过时?
此警告中提到的竞争条件是 TestProbe 设计中固有的,但发生死锁的可能性相当小,监视必须与向另一个方向发送消息的时间完全同时发生,并且两者都必须发生在不同的线程中。由于创建顶级参与者的方式,在极少数情况下可以观察到后者。
所有这些都相当棘手,其中 none 适用于为 Akka Typed 编写和执行测试的方式,我期待着何时成为唯一使用的模式。
在 akka 2.3.9 documentation 中有一个警告:
Any message send from a
TestProbe
to another actor which runs on theCallingThreadDispatcher
runs the risk of dead-lock, if that other actor might also send to this probe. The implementation ofTestProbe.watch
andTestProbe.unwatch
will also send a message to the watchee, which means that it is dangerous to try watching e.g.TestActorRef
from aTestProbe
.
我试图在测试中使用 TestProbe
和 TestActorRef
重现所描述的死锁情况,因为两者都使用 CallingThreadDispatcher
class DeadlockTest extends TestKit(ActorSystem()) with FunSuiteLike {
test("deadlock attempt") {
val b = TestProbe()
val a = TestActorRef(new Actor {
override def preStart() = b.ref ! "pre"
def receive = {
case msg =>
sender ! msg
context.stop(self)
}
})
b.watch(a)
b.send(a, "foo")
b.expectMsg("pre")
b.expectMsg("foo")
b.expectTerminated(a)
b.unwatch(a)
}
}
我预计测试会挂起,但它成功通过了。
警告是否仍然相关并且死锁的可能性很高还是已过时?
此警告中提到的竞争条件是 TestProbe 设计中固有的,但发生死锁的可能性相当小,监视必须与向另一个方向发送消息的时间完全同时发生,并且两者都必须发生在不同的线程中。由于创建顶级参与者的方式,在极少数情况下可以观察到后者。
所有这些都相当棘手,其中 none 适用于为 Akka Typed 编写和执行测试的方式,我期待着何时成为唯一使用的模式。