[Twisted-Python] Unruly Callback Code
Justin Johnson
justinjohnson at fastmail.fm
Tue Aug 5 12:32:06 MDT 2003
How's it look now? I still need to add appropriate errbacks for each
deferred in the deferred list, as opposed to using an errback on the
entire list. Any other suggestions (even minor) about variable/function
naming or anything else?
# Subcommand: mkvob
def cmd_mkvob(self):
"""Usage: mkvob -v vob-tag[,vob-tag,...] -o site [-g group] [-s site,site,...]
"""
options = self.config.subOptions
original_site = options["original"]
group = options["group"]
vobs = options["vobs"].split(",")
sites = []
if options["sites"] is not None:
sites = options["sites"].split(",")
def renameReplica(results, perspective, vobs, original_site):
d = perspective.callRemote("renameReplica", vobs, "original", original_site)
return d
def mkRepExport(results, perspective, vobs, sites):
d = perspective.callRemote("mkReplicaExport", vobs, sites)
return d
def _stop(fail):
reactor.stop()
return fail
def mkRepImport(results, perspective, vobs, sites):
if len(vobs) > 0 and len(sites) > 0:
deferreds = []
for site in sites:
def applyTriggers(results, perspective, vobs):
d = perspective.callRemote("applyTriggers", vobs)
return d
def gotObject(perspective, vobs):
d = perspective.callRemote("mkReplicaImport", vobs)
d.addCallback(applyTriggers, perspective, vobs)
return d
d = self.connectToServer(config.siteToServer[site])
d.addCallback(gotObject, vobs)
deferreds.append(d)
return defer.DeferredList(deferreds)
return results
def gotObject(perspective, vobs, group, original_site, sites):
d = perspective.callRemote("mkvob", vobs, group)
d.addCallback(renameReplica, perspective, vobs, original_site)
d.addCallback(mkRepExport, perspective, vobs, sites)
d.addCallback(mkRepImport, perspective, vobs, sites)
d.addErrback(log.err)
d.addBoth(_stop)
return d
# Connect to the server and start the chain of deferreds
d = self.connectToServer(config.siteToServer[original_site])
d.addCallback(gotObject, vobs, group, original_site, sites)
reactor.run()
On Tue, 5 Aug 2003 19:02:44 +0300, "Tommi Virtanen"
<tv at twistedmatrix.com> said:
> On Tue, Aug 05, 2003 at 08:02:31AM -0600, Justin Johnson wrote:
> > Would someone mind looking at the code below and suggesting ways to clean
> > this up?
>
> > # Subcommand: mkvob
> > def cmd_mkvob(self):
> > """Usage: mkvob -v vob-tag[,vob-tag,...] -o site [-g group] [-s site,site,...]
> > """
> > options = self.config.subOptions
> > original_site = options["original"]
> > group = options["group"]
> > vobs = options["vobs"].split(",")
> > sites = []
> > if options["sites"] != None:
> if options["sites"] is not None:
> > sites = options["sites"].split(",")
> >
> > def gotObject(object):
> def gotObject(object, vobs, group):
> > self.perspectives[original_site] = object
> > print "Successfully connected to %s (%s)." % (original_site, config.siteToServer[original_site])
> > print "Calling remote mkvob ..."
> > d = object.callRemote("mkvob", vobs, group)
> > return d
>
> I'd actually avoid passing vobs and group into gotObject like
> that. Just have them as parameters; that means the function
> body is independent of its location, which I consider a lot
> cleaner.
>
> > def renameReplica(results, vobs, original_site):
> > # Do I have to connect again to do this?
> > obj = self.perspectives[original_site]
> > obj.callRemote("renameReplica", vobs, "original", original_site)
> > return obj
> >
> > def mkRepExport(results, vobs, sites, original_site):
> > obj = self.perspectives[original_site]
> > d = obj.callRemote("mkReplicaExport", vobs, sites)
> > return d
>
> The tricks you play with self.perspectives are quite
> confusing, IMHO. I'd be more inclined to adding the
> callbacks accessing self.perspectives at a stage where
> I could pass them the perspective as an argument.
> That is,
>
> def gotObject(object, vobs, group):
> d = object.callRemote("mkvob", vobs, group)
> d.addCallback(renameReplica, object, vobs, original_site)
> d.addCallback(mkRepExport, object, vobs, sites, original_site)
> d.addCallback(mkRepImport, object, vobs, sites)
> return d
>
> Also, object is a bad name, as that name means other things in
> python2.2.
>
> > def _stop(*args):
> > print "The mkvob operation completed successfully"
> > reactor.stop()
> > return args
>
> def _stop(fail):
> reactor.stop()
> return fail
>
> That's not true, _stop is also called on errors.
>
> Also, _stop gets no extra arguments in .addBoth, so args=(aFailure,)
> and then you return that tuple..
>
> > def mkRepImport(results, vobs, sites):
> > if len(vobs) > 0 and len(sites) > 0:
> > deferreds = []
> > for site in sites:
> > def onSuccess(object, site):
> > self.perspectives[site] = object
> > d = object.callRemote("mkReplicaImport", vobs)
> > return d
> > def applyTriggers(results, vobs, site):
> > obj = self.perspectives[site]
> > d = obj.callRemote("applyTriggers", vobs)
> > return d
> > d = self.connectToServer(config.siteToServer[site])
> > d.addCallback(onSuccess, site).addErrback(log.err)
> > d.addCallback(applyTriggers, vobs, site).addErrback(log.err)
> > deferreds.append(d)
> > return defer.DeferredList(deferreds)
> > return results
>
> You just stepped in the DeferredList trap. DeferredList
> _never_ .errback()s unless it's told to fireOnOneErrback.
> That means you miss what errors might have happened.
>
> And fireOnOneErrback isn't normally what you want; you want
> to handle the results one by one.
>
> > d = self.connectToServer(config.siteToServer[original_site])
> > d.addCallbacks(gotObject, gotNoObject)
> > d.addCallback(renameReplica, vobs, original_site).addErrback(log.err)
> > d.addCallback(mkRepExport, vobs, sites, original_site).addErrback(log.err)
> > d.addCallback(mkRepImport, vobs, sites).addErrback(log.err)
>
> There's no need to .addErrback that much. There's probably no
> reason to have gotNoObject special cased, and handle later
> errors just with log.err.
>
> d = self.connectToServer(config.siteToServer[original_site])
> d.addCallback(gotObject, vobs, group)
> d.addCallback(renameReplica, vobs, original_site)
> d.addCallback(mkRepExport, vobs, sites, original_site)
> d.addCallback(mkRepImport, vobs, sites)
> d.addErrback(log.err)
>
> --
> :(){ :|:&};:
>
> _______________________________________________
> Twisted-Python mailing list
> Twisted-Python at twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
More information about the Twisted-Python
mailing list