[Twisted-Python] deferring result to PB a callRemote method
clawsicus at gmail.com
Mon Jan 18 09:32:05 EST 2010
I am writing a tool for work that will run various software development aids
such as message capturing and diagnostic control of system processes.
My current design strategy is to implement these aids as plugins (not
twisted plugins) to a generic plugin runner rather than stand alone
The plugins are spawned as separate processes by the plugin-runner and
communicate using Perspective Broker during the plugin installation and
Some plugins may take a while to shutdown as they need to close
sockets, finalize files, move large files, etc.
I would like to instruct the plugin to shutdown and be told when it is
finally ready to be shut down.
To date all my callRemote methods have effectively returned immediately. For
My question to the list was going to be: Is there a pattern/example I could
follow where I could call plugin.callRemote("shutdown") on a plugin and not
return a result to the plugin-runner until the plugin has completed all
it's, potentially, long running activities? However, while I was trying to
write a small code snippet that would demonstrate what I was wanting, I
think I got it working.
I think the simple answer to my question is to just return a deferred as the
result to the callRemote("shutdown") method and trigger it as normal.
Google is my friend but I could not find examples of this usage. Is there
any references to this usage in the twisted docs?
Below (and attached in case the formatting goes screwy) is a short example
which emulates a long running shutdown activity performed by the plugin
prior to shutdown.
It seems to delay the processing of the callRemote("shutdown") result until
the plugin has completed it's long running activity.
I have omitted the separate process stuff as it didn't seem relevant for
Is the following code snippet the standard/normal way to defer the return
result of a callRemote method call?
If this is the normal way, how does triggering the deferred on the plugin
(client) side also trigger the same/copy deferred returned to the
Is this PB magic, somehow managing deferreds across the PB interface?
from twisted.internet import reactor, defer
from twisted.spread import pb
""" Plugin client interface exposed to PluginServer's """
def __init__(self, shutdownCallback):
self.shutdownHandler = shutdownCallback
""" Instruct Plugin to shutdown """
print "plugin instructed to shutdown"
d = defer.Deferred()
""" Plugin server interface exposed to PluginClient's """
def remote_set_client_perspective(self, pluginRef):
print "plugin-runner got client reference"
reactor.callLater(1.0, self.shutdown_plugin, pluginRef)
def shutdown_plugin(self, pluginRef):
def pluginShutdownCompleted(result, startTime):
endTime = datetime.datetime.now()
print "Plugin shutdown took %s to complete." % (endTime -
print "plugin-runner asking plugin to shutdown"
d = pluginRef.callRemote("shutdown")
def shutdown(self, _):
""" Start a plugin communications server """
print "starting server"
def startPluginClient(port, shutdownHandler):
""" Start a plugin communications client """
def gotServerPerspective(serverPerspective, pluginPerspective):
""" Give the plugin-runner this client's perspective """
print "starting plugin"
client = PluginClient(shutdownHandler)
factory = pb.PBClientFactory()
reactor.connectTCP(host='localhost', port=port, factory=factory)
return factory.getRootObject().addCallback(gotServerPerspective, client)
if __name__ == "__main__":
port = 42155
def longRunningAction(d, countDown=10):
""" Emulate long running shutdown activities """
print "shuting down in %i seconds" % countDown
if countDown == 0:
countDown -= 1
reactor.callLater(1, longRunningAction, d, countDown)
# start plugin-runner
# start plugin
reactor.callLater(2.0, startPluginClient, port, longRunningAction)
-------------- next part --------------
An HTML attachment was scrubbed...
-------------- next part --------------
A non-text attachment was scrubbed...
Size: 2856 bytes
Desc: not available
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20100119/a35c15fe/attachment-0001.obj
More information about the Twisted-Python