Skip to content

Commit

Permalink
Add actorSystemShutdown call to allow an actor to shutdown the entire…
Browse files Browse the repository at this point in the history
… local actor system (Issue #24)
  • Loading branch information
kwquick committed Nov 10, 2016
1 parent b397ce6 commit 7a9e0b4
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 13 deletions.
17 changes: 17 additions & 0 deletions doc/using.org
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,23 @@ class MyActor(Actor):
(e.g. the same address that would be provided in the
[[*ActorSystemConventionUpdate][ActorSystemConventionUpdate]] messages).

** actorSystemShutdown

The ~actorSystemShutdown()~ method can be called by an actor to
shutdown the *entire* local Actor System, including all Actors
currently running under that system. This method should not
normally be needed and is intended only for situations where the
local running system is being deactivated.

The shutdown operation will be initiated immediately:
ActorExitRequests will be sent to all locally running Actors.

#+BEGIN_SRC python
self.actorSystemShutdown()
#+END_SRC

Use this method with caution.

** ActorTypeDispatcher

An alternative base class for creating Actors is the
Expand Down
8 changes: 8 additions & 0 deletions thespian/actors.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,14 @@ def deRegisterRemoteSystem(self, remoteAddress):
self._myRef.deRegisterRemoteSystem(remoteAddress)


def actorSystemShutdown(self):
"""Allows an Actor to request the shutdown of the entire Actor System.
This is dangerous and fatal for the entire local actor
system; use with care.
"""
self._myRef.actorSystemShutdown()


class ActorSystemMessage(object):
"""Base class for all ActorSystem Messages for easier isinstance
identification.
Expand Down
4 changes: 4 additions & 0 deletions thespian/system/actorManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,7 @@ def deRegisterRemoteSystem(self, remoteAddress):
if isinstance(remoteAddress, ActorAddress) else
self.transport.getAddressFromString(remoteAddress),
preRegistered=True)))


def actorSystemShutdown(self):
self._send_intent(TransmitIntent(self._adminAddr, SystemShutdown()))
21 changes: 8 additions & 13 deletions thespian/test/test_actorSystemRestart.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from thespian.test import *
import time
from datetime import timedelta
import multiprocessing


ask_wait = timedelta(seconds=8)
Expand All @@ -33,6 +32,11 @@ def receiveMessage(self, msg, sender):
tgt = msg.next(sender)
self.send(tgt, msg)

class SysStopper(Actor):
def receiveMessage(self, msg, sender):
if not isinstance(msg, ActorExitRequest):
self.actorSystemShutdown()


class TestFuncSystemRestart(object):

Expand Down Expand Up @@ -62,18 +66,14 @@ def testConnectToExistingActorSystem(self, asys):
assert [parent1,parent,parent1] == r.pathdone

finally:
pass

aS.shutdown()
aS.tell(aS.createActor(SysStopper), 'shut it down')

def testConnectToStoppingActorSystem(self, asys):
parent1 = asys.createActor(Parent)
r = asys.ask(parent1, 'Hello', ask_wait)
assert 'Hi' == r
asys.tell(parent1, 'Sleep') # Parent will prevent shutdown for a little while
p = multiprocessing.Process(target=stopAdmin, args=(asys,))

p.start()
asys.tell(asys.createActor(SysStopper), 'stop system')

# Access system internals to make singleton "forget" about the
# current ActorSystem. This is done so that a new local
Expand All @@ -95,9 +95,4 @@ def testConnectToStoppingActorSystem(self, asys):
pass # this is expected, although it takes a while to get (10s)
finally:
pass
aS.shutdown()
p.join()


def stopAdmin(actorsys):
actorsys.shutdown()
aS.tell(aS.createActor(SysStopper), 'shut it down')

0 comments on commit 7a9e0b4

Please sign in to comment.