document ActorDSL, see #2411
This commit is contained in:
parent
ca75bbc2a0
commit
0489c5daf1
2 changed files with 70 additions and 0 deletions
|
|
@ -7,7 +7,9 @@ package akka.actor
|
|||
import language.postfixOps
|
||||
|
||||
import akka.testkit.{ AkkaSpec, EventFilter }
|
||||
//#import
|
||||
import akka.actor.ActorDSL._
|
||||
//#import
|
||||
import akka.event.Logging.Warning
|
||||
import scala.concurrent.{ Await, Future }
|
||||
import scala.concurrent.util.duration._
|
||||
|
|
@ -88,11 +90,13 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
"A lightweight creator" must {
|
||||
|
||||
"support creating regular actors" in {
|
||||
//#simple-actor
|
||||
val a = actor(new Act {
|
||||
become {
|
||||
case "hello" ⇒ sender ! "hi"
|
||||
}
|
||||
})
|
||||
//#simple-actor
|
||||
|
||||
implicit val i = inbox()
|
||||
a ! "hello"
|
||||
|
|
@ -100,10 +104,12 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"support setup/teardown" in {
|
||||
//#simple-start-stop
|
||||
val a = actor(new Act {
|
||||
whenStarting { testActor ! "started" }
|
||||
whenStopping { testActor ! "stopped" }
|
||||
})
|
||||
//#simple-start-stop
|
||||
|
||||
system stop a
|
||||
expectMsg("started")
|
||||
|
|
@ -111,6 +117,7 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
}
|
||||
|
||||
"support restart" in {
|
||||
//#failing-actor
|
||||
val a = actor(new Act {
|
||||
become {
|
||||
case "die" ⇒ throw new Exception
|
||||
|
|
@ -118,6 +125,7 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
whenFailing { (cause, msg) ⇒ testActor ! (cause, msg) }
|
||||
whenRestarted { cause ⇒ testActor ! cause }
|
||||
})
|
||||
//#failing-actor
|
||||
|
||||
EventFilter[Exception](occurrences = 1) intercept {
|
||||
a ! "die"
|
||||
|
|
@ -129,10 +137,12 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
"support superviseWith" in {
|
||||
val a = actor(new Act {
|
||||
val system = null // shadow the implicit system
|
||||
//#supervise-with
|
||||
superviseWith(OneForOneStrategy() {
|
||||
case e: Exception if e.getMessage == "hello" ⇒ SupervisorStrategy.Stop
|
||||
case _: Exception ⇒ SupervisorStrategy.Resume
|
||||
})
|
||||
//#supervise-with
|
||||
val child = actor("child")(new Act {
|
||||
whenFailing { (_, _) ⇒ }
|
||||
become {
|
||||
|
|
@ -157,6 +167,8 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
|
||||
"supported nested declaration" in {
|
||||
val system = this.system
|
||||
//#nested-actor
|
||||
// here we pass in the ActorRefFactory explicitly as an example
|
||||
val a = actor(system, "fred")(new Act {
|
||||
val b = actor("barney")(new Act {
|
||||
whenStarting { context.parent ! ("hello from " + self) }
|
||||
|
|
@ -165,11 +177,13 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
case x ⇒ testActor ! x
|
||||
}
|
||||
})
|
||||
//#nested-actor
|
||||
expectMsg("hello from Actor[akka://ActorDSLSpec/user/fred/barney]")
|
||||
lastSender must be(a)
|
||||
}
|
||||
|
||||
"support Stash" in {
|
||||
//#act-with-stash
|
||||
val a = actor(new ActWithStash {
|
||||
become {
|
||||
case 1 ⇒ stash()
|
||||
|
|
@ -179,6 +193,7 @@ class ActorDSLSpec extends AkkaSpec {
|
|||
}
|
||||
}
|
||||
})
|
||||
//#act-with-stash
|
||||
|
||||
a ! 1
|
||||
a ! 2
|
||||
|
|
|
|||
|
|
@ -153,6 +153,61 @@ When spawning actors for specific sub-tasks from within an actor, it may be conv
|
|||
there is not yet a way to detect these illegal accesses at compile time.
|
||||
See also: :ref:`jmm-shared-state`
|
||||
|
||||
The Actor DSL
|
||||
-------------
|
||||
|
||||
Simple actors—for example one-off workers or even when trying things out in the
|
||||
REPL—can be created more concisely using the :class:`Act` trait. The supporting
|
||||
infrastructure is bundled in the following import:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#import
|
||||
|
||||
This import is assumed for all code samples throughout this section. To defined
|
||||
a simple actor, the following is sufficient:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#simple-actor
|
||||
|
||||
Here, :meth:`actor` takes the role of either ``system.actorOf`` or
|
||||
``context.actorOf``, depending on which context it is called in: it takes an
|
||||
implicit :class:`ActorRefFactory`, which within an actor is available in the
|
||||
form of the ``implicit val context: ActorContext``. Outside of an actor, you’ll
|
||||
have to either declare an implicit :class:`ActorSystem`, or you can give the
|
||||
factory explicitly (see further below).
|
||||
|
||||
Life-cycle hooks are also exposed as DSL elements, where later invocations of
|
||||
the methods shown below will replace the contents of the respective hooks:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#simple-start-stop
|
||||
|
||||
The above is enough if the logical life-cycle of the actor matches the restart
|
||||
cycles (i.e. ``whenStopping`` is executed before a restart and ``whenStarting``
|
||||
afterwards). If that is not desired, use the following two hooks:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#failing-actor
|
||||
|
||||
It is also possible to create nested actors, i.e. grand-children, like this:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#nested-actor
|
||||
|
||||
.. note::
|
||||
|
||||
In some cases it will be necessary to explicitly pass the
|
||||
:class:`ActorRefFactory` to the :meth:`actor()` method (you will notice when
|
||||
the compiler tells you about ambiguous implicits).
|
||||
|
||||
The grand-child will be supervised by the child; the supervisor strategy for
|
||||
this relationship can also be configured using a DSL element:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#supervise-with
|
||||
|
||||
Last but not least there is a little bit of convenience magic built-in, which
|
||||
detects if the runtime class of the statically given actor subtype extends the
|
||||
:class:`Stash` trait (this is a complicated way of saying that ``new Act with
|
||||
Stash`` would not work because its runtime erased type is just an anonymous
|
||||
subtype of ``Act``). If you want to use this magic, simply extend
|
||||
:class:`ActWithStash`:
|
||||
|
||||
.. includecode:: ../../../akka-actor-tests/src/test/scala/akka/actor/ActorDSLSpec.scala#act-with-stash
|
||||
|
||||
Actor API
|
||||
=========
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue