Merge pull request #1053 from akka/wip-2916-CTD-warning-∂π
document deadlock risk of TestProbe.watch(TestActorRef), see #2916
This commit is contained in:
commit
414fddf1d6
4 changed files with 58 additions and 0 deletions
|
|
@ -17,6 +17,7 @@ import akka.actor.ActorRef;
|
||||||
import akka.actor.ActorSystem;
|
import akka.actor.ActorSystem;
|
||||||
import akka.actor.Kill;
|
import akka.actor.Kill;
|
||||||
import akka.actor.Props;
|
import akka.actor.Props;
|
||||||
|
import akka.actor.Terminated;
|
||||||
import akka.actor.UntypedActor;
|
import akka.actor.UntypedActor;
|
||||||
import akka.actor.UntypedActorFactory;
|
import akka.actor.UntypedActorFactory;
|
||||||
import scala.concurrent.Await;
|
import scala.concurrent.Await;
|
||||||
|
|
@ -300,6 +301,19 @@ public class TestKitDocTest {
|
||||||
//#test-special-probe
|
//#test-special-probe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void demonstrateWatch() {
|
||||||
|
final ActorRef target = system.actorFor("/buh");
|
||||||
|
//#test-probe-watch
|
||||||
|
new JavaTestKit(system) {{
|
||||||
|
final JavaTestKit probe = new JavaTestKit(system);
|
||||||
|
probe.watch(target);
|
||||||
|
final Terminated msg = probe.expectMsgClass(Terminated.class);
|
||||||
|
assertEquals(msg.getActor(), target);
|
||||||
|
}};
|
||||||
|
//#test-probe-watch
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void demonstrateReply() {
|
public void demonstrateReply() {
|
||||||
//#test-probe-reply
|
//#test-probe-reply
|
||||||
|
|
|
||||||
|
|
@ -387,6 +387,23 @@ You have complete flexibility here in mixing and matching the
|
||||||
name for it. In real life your code will probably be a bit more complicated
|
name for it. In real life your code will probably be a bit more complicated
|
||||||
than the example given above; just use the power!
|
than the example given above; just use the power!
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
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 :meth:`TestProbe.watch` and
|
||||||
|
:meth:`TestProbe.unwatch` will also send a message to the watchee, which
|
||||||
|
means that it is dangerous to try watching e.g. :class:`TestActorRef` from a
|
||||||
|
:meth:`TestProbe`.
|
||||||
|
|
||||||
|
Watching Other Actors from Probes
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A :class:`JavaTestKit` can register itself for DeathWatch of any other actor:
|
||||||
|
|
||||||
|
.. includecode:: code/docs/testkit/TestKitDocTest.java
|
||||||
|
:include: test-probe-watch
|
||||||
|
|
||||||
Replying to Messages Received by Probes
|
Replying to Messages Received by Probes
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,16 @@ class TestkitDocSpec extends AkkaSpec with DefaultTimeout with ImplicitSender {
|
||||||
//#test-special-probe
|
//#test-special-probe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"demonstrate probe watch" in {
|
||||||
|
import akka.testkit.TestProbe
|
||||||
|
val target = system.actorFor("/buh")
|
||||||
|
//#test-probe-watch
|
||||||
|
val probe = TestProbe()
|
||||||
|
probe watch target
|
||||||
|
probe.expectMsgType[Terminated].actor must be(target)
|
||||||
|
//#test-probe-watch
|
||||||
|
}
|
||||||
|
|
||||||
"demonstrate probe reply" in {
|
"demonstrate probe reply" in {
|
||||||
import akka.testkit.TestProbe
|
import akka.testkit.TestProbe
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
|
||||||
|
|
@ -446,6 +446,23 @@ facilities with your own checks and choosing an intuitive name for it. In real
|
||||||
life your code will probably be a bit more complicated than the example given
|
life your code will probably be a bit more complicated than the example given
|
||||||
above; just use the power!
|
above; just use the power!
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
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 :meth:`TestProbe.watch` and
|
||||||
|
:meth:`TestProbe.unwatch` will also send a message to the watchee, which
|
||||||
|
means that it is dangerous to try watching e.g. :class:`TestActorRef` from a
|
||||||
|
:meth:`TestProbe`.
|
||||||
|
|
||||||
|
Watching Other Actors from Probes
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
A :class:`TestKit` can register itself for DeathWatch of any other actor:
|
||||||
|
|
||||||
|
.. includecode:: code/docs/testkit/TestkitDocSpec.scala
|
||||||
|
:include: test-probe-watch
|
||||||
|
|
||||||
Replying to Messages Received by Probes
|
Replying to Messages Received by Probes
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue