[Twisted-Python] patch for background processing (delay 0)
Jp Calderone
exarkun at divmod.com
Tue May 18 22:39:49 MDT 2004
Bill la Forge wrote:
> I do hereby consigne all copyrights for this patch to Glyph, as required
> by Twisted: http://www.twistedmatrix.com/developers/contributing
>
> Appologies for not using diff, but I am not yet able to download the
> cygwin package. (perhaps Sunday bandwidth here will be better!)
>
> The first part was developed by twisted:
>
> def callLater(self, _seconds, _f, *args, **kw):
> """See twisted.internet.interfaces.IReactorTime.callLater.
> """
> assert callable(_f), "%s is not callable" % _f
> assert sys.maxint >= _seconds >= 0, \
> "%s is not greater than or equal to 0 seconds" % (_seconds,)
> # patch follows
> # tple = DelayedCall(seconds() + _seconds, _f, args, kw,
> if _seconds != 0:
> ttc = _seconds + seconds()
> else:
> ttc = _seconds
> tple = DelayedCall(ttc, _f, args, kw,
> # end of patch
> self._pendingTimedCalls.remove,
> self._resetCallLater)
Additionally, I would suggest that _pendingTimedCalls.append(tple) be
used instead of the insort() call when _seconds is 0. This speeds up
the case of a callLater(0) loop by about 10%.
> insort(self._pendingTimedCalls, tple)
> return tple
> The second part is my contribution:
>
> def runUntilCurrent(self):
> """Run all pending timed calls.
> """
> if self.threadCallQueue:
> # Keep track of how many calls we actually make, as we're
> # making them, in case another call is added to the queue
> # while we're in this loop.
> count = 0
> for (f, a, kw) in self.threadCallQueue:
> try:
> f(*a, **kw)
> except:
> log.err()
> count += 1
> del self.threadCallQueue[:count]
> now = seconds()
> # patch follows
> # while self._pendingTimedCalls and
> (self._pendingTimedCalls[-1].time <= now):
> # call = self._pendingTimedCalls.pop()
This approach might be a bit faster than pop in a loop
i = bisect.bisect_left(self._pendingTimedCalls, now)
do = self._pendingTimedCalls[i:]
self._pendingtimedCalls = self._pendingTimedCalls[:i]
or it may not be, given how much more memory it allocates.
> do=[]
> while self._pendingTimedCalls and
> (self._pendingTimedCalls[-1].time <= now):
> do.append(self._pendingTimedCalls.pop())
> for call in do:
> # end of patch
> try:
> call.called = 1
> call.func(*call.args, **call.kw)
> except:
> log.deferr()
> if hasattr(call, "creator"):
> e = "\n"
> e += " C: previous exception occurred in " + \
> "a DelayedCall created here:\n"
> e += " C:"
> e += "".join(call.creator).rstrip().replace("\n","\n
> C:")
> e += "\n"
> log.msg(e)
> Sincerly,
>
Thanks for the contribution :) By the way, for a slightly less hefty
download than cygwin, check out http://unxutils.sourceforge.net/ (kindly
pointed out by bear in #twisted). It includes a Windows-native diff tool.
Jp
More information about the Twisted-Python
mailing list