#! /usr/bin/python from twisted.spread import pb, jelly from twisted.python import log from twisted.internet import reactor class MyException(pb.Error): pass class MyOtherException(pb.Error): pass class ScaryObject: # not safe for serialization pass def worksLike(obj): # the callback/errback sequence in class One works just like an # asynchronous version of the following: try: response = obj.callMethod(name, arg) except pb.DeadReferenceError: print " stale reference: the client disconnected or crashed" except jelly.InsecureJelly: print " InsecureJelly: you tried to send something unsafe to them" except (MyException, MyOtherException): print " remote raised a MyException" # or MyOtherException except: print " something else happened" else: print " method successful, response:", response class One: def worked(self, response): print " method successful, response:", response def check_InsecureJelly(self, failure): failure.trap(jelly.InsecureJelly) print " InsecureJelly: you tried to send something unsafe to them" return None def check_MyException(self, failure): which = failure.trap(MyException, MyOtherException) if which == MyException: print " remote raised a MyException" else: print " remote raised a MyOtherException" return None def catch_everythingElse(self, failure): print " something else happened" log.err(failure) return None def doCall(self, explanation, arg): print explanation try: deferred = self.remote.callRemote("fooMethod", arg) deferred.addCallback(self.worked) deferred.addErrback(self.check_InsecureJelly) deferred.addErrback(self.check_MyException) deferred.addErrback(self.catch_everythingElse) except pb.DeadReferenceError: print " stale reference: the client disconnected or crashed" def callOne(self): self.doCall("callOne: call with safe object", "safe string") def callTwo(self): self.doCall("callTwo: call with dangerous object", ScaryObject()) def callThree(self): self.doCall("callThree: call that raises remote exception", "panic!") def callShutdown(self): print "telling them to shut down" self.remote.callRemote("shutdown") def callFour(self): self.doCall("callFour: call on stale reference", "dummy") def got_obj(self, obj): self.remote = obj reactor.callLater(1, self.callOne) reactor.callLater(2, self.callTwo) reactor.callLater(3, self.callThree) reactor.callLater(4, self.callShutdown) reactor.callLater(5, self.callFour) reactor.callLater(6, reactor.stop) deferred = pb.getObjectAt("localhost", 8800, 30) deferred.addCallback(One().got_obj) reactor.run()