add terminate(Shutdown) to FSM.postStop

This commit is contained in:
Roland 2011-05-31 22:27:18 +02:00
parent 89bc1943c3
commit ca36b556fb
3 changed files with 32 additions and 3 deletions

View file

@ -155,7 +155,6 @@ class FSMActorSpec extends WordSpec with MustMatchers with TestKit {
case Ev("go") goto(2)
}
}).start()
val reff = testActor
val logger = Actor.actorOf(new Actor {
def receive = {
case x testActor forward x
@ -169,5 +168,18 @@ class FSMActorSpec extends WordSpec with MustMatchers with TestKit {
EventHandler.removeListener(logger)
}
"run onTermination upon ActorRef.stop()" in {
lazy val fsm = new Actor with FSM[Int, Null] {
startWith(1, null)
when(1) { NullFunction }
onTermination {
case x testActor ! x
}
}
val ref = Actor.actorOf(fsm).start()
ref.stop()
expectMsg(fsm.StopEvent(Shutdown, 1, null))
}
}
}

View file

@ -480,6 +480,8 @@ trait FSM[S, D] extends ListenerManagement {
}
}
override def postStop { terminate(Shutdown) }
private def terminate(reason: Reason) = {
reason match {
case Failure(ex: Throwable) EventHandler.error(ex, self, "terminating due to Failure")

View file

@ -430,8 +430,8 @@ queued it. The status of any timer may be inquired with
These named timers complement state timeouts because they are not affected by
intervening reception of other messages.
Termination
-----------
Termination from Inside
-----------------------
The FSM is stopped by specifying the result state as
@ -471,6 +471,21 @@ a :class:`StopEvent(reason, stateName, stateData)` as argument:
As for the :func:`whenUnhandled` case, this handler is not stacked, so each
invocation of :func:`onTermination` replaces the previously installed handler.
Termination from Outside
------------------------
When an :class:`ActorRef` associated to a FSM is stopped using the
:meth:`stop()` method, its :meth:`postStop` hook will be executed. The default
implementation by the :class:`FSM` trait is to execute the
:meth:`onTermination` handler if that is prepared to handle a
:obj:`StopEvent(Shutdown, ...)`.
.. warning::
In case you override :meth:`postStop` and want to have your
:meth:`onTermination` handler called, do not forget to call
``super.postStop``.
Examples
========