[Twisted-Python] Dealing with an intermittent PB server
Phil Mayers
p.mayers at imperial.ac.uk
Wed Feb 16 18:05:22 MST 2005
On Wed, Feb 16, 2005 at 04:28:32AM +0000, Jp Calderone wrote:
>On Tue, 15 Feb 2005 19:56:15 -0800, Dave Cook <daverz at gmail.com> wrote:
>>I'm rendering the results of a remote method call:
>>
>> def data_tableList(self, ctx, data):
>> ...
>> d = self.pbClientFactory.login(creds)
>> d.addCallback(lambda object: object.callRemote("foo"))
>> return d
>
> Always always always use errbacks. *Especially* for Deferreds that can
>fail due to transient network conditions.
See, that depends. I ran into this just today in fact, and found that if
the server has gone away, then you'll get an exception *right then*, not
via the errback:
def do_stop(self):
try:
self.root.callRemote('stop', self).addCallbacks(self.stop, self.err)
except pb.DeadReferenceError, re:
self.stale()
Why, why, why why why doesn't the DeadReferenceError go down the
errback? As it is, the code has to be littered with both synchronous and
asynchronous error handling, which is needlessly irritating, surely?
The original poster may find his problem was a DeadReferenceError that's
getting silently eaten (or just not GCed right away) by the framework,
as I did.
For the original poster, here's what I've got:
class Thing:
def __init__(self):
self.root = None
self.connect()
def connect(self):
f = pb.PBClientFactory()
reactor.connectTCP(host, port, f)
f.getRootObject().addCallbacks(self.connect_ok, self.connect_fail)
def connect_ok(self, root):
self.root = root
def connect_fail(self, f):
self.banner(f.getErrorMessage())
reactor.callLater(1, self.connect)
def stale(self):
self.root = None
self.connect()
def start(self):
if not self.root:
self.banner("Connection in progress, please wait")
return
try:
self.root.callRemote('start').addCallbacks(self.start2, self.err)
self.banner("sent...")
except pb.DeadReferenceError, re:
self.stale()
self.banner("Connection dropped, reconnecting")
def start2(self, dummy):
self.banner("started")
def err(self, f):
self.banner(f.getErrorMessage())
More information about the Twisted-Python
mailing list