[Twisted-Python] patch for background processing (delay 0)

Jp Calderone exarkun at divmod.com
Wed May 19 00:39:49 EDT 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