Created the ExtendedLoopingCall class for making resheduling of scripts a little more robust
This commit is contained in:
parent
d159f6731d
commit
6e4591d633
1 changed files with 80 additions and 1 deletions
|
|
@ -6,7 +6,7 @@ It also defines a few common scripts.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from time import time
|
from time import time
|
||||||
from twisted.internet.defer import maybeDeferred
|
from twisted.internet.defer import maybeDeferred, Deferred
|
||||||
from twisted.internet.task import LoopingCall
|
from twisted.internet.task import LoopingCall
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
@ -23,6 +23,85 @@ _SESSIONS = None
|
||||||
_ATTRIBUTE_CACHE_MAXSIZE = settings.ATTRIBUTE_CACHE_MAXSIZE
|
_ATTRIBUTE_CACHE_MAXSIZE = settings.ATTRIBUTE_CACHE_MAXSIZE
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
print "Called: %s " % time()
|
||||||
|
|
||||||
|
class ExtendedLoopingCall(LoopingCall):
|
||||||
|
"""
|
||||||
|
LoopingCall that can start at a delay different
|
||||||
|
than self.interval.
|
||||||
|
"""
|
||||||
|
start_delay = None
|
||||||
|
|
||||||
|
def start(self, interval, now=True, start_delay=None):
|
||||||
|
"""
|
||||||
|
Start running function every interval seconds.
|
||||||
|
|
||||||
|
This overloads the LoopingCall default by offering
|
||||||
|
the start_delay keyword.
|
||||||
|
|
||||||
|
start_delay: The number of seconds before starting.
|
||||||
|
If None, wait interval seconds. Only
|
||||||
|
valid is now is False.
|
||||||
|
"""
|
||||||
|
assert not self.running, ("Tried to start an already running "
|
||||||
|
"LoopingCall.")
|
||||||
|
if interval < 0:
|
||||||
|
raise ValueError, "interval must be >= 0"
|
||||||
|
self.running = True
|
||||||
|
d = self.deferred = Deferred()
|
||||||
|
self.starttime = self.clock.seconds()
|
||||||
|
self._lastTime = self.starttime
|
||||||
|
self.interval = interval
|
||||||
|
if now:
|
||||||
|
self()
|
||||||
|
elif start_delay is not None and start_delay >= 0:
|
||||||
|
self.interval = start_delay
|
||||||
|
self._reschedule()
|
||||||
|
# this is set after the _reshedule call to make
|
||||||
|
# next_call find it until next reshedule.
|
||||||
|
self.start_delay = start_delay
|
||||||
|
self.interval = interval
|
||||||
|
else:
|
||||||
|
self._reschedule()
|
||||||
|
return d
|
||||||
|
|
||||||
|
def _reschedule(self):
|
||||||
|
"Handle delayed call so next_call get it right"
|
||||||
|
self.start_delay = None
|
||||||
|
super(ExtendedLoopingCall, self)._reschedule()
|
||||||
|
|
||||||
|
def reset(self, force_call=True):
|
||||||
|
"""
|
||||||
|
Reset the loop timer. The task must already be started.
|
||||||
|
|
||||||
|
force_call - trigger the callback function
|
||||||
|
"""
|
||||||
|
assert self.running, ("Tried to reset a LoopingCall that was "
|
||||||
|
"not running.")
|
||||||
|
if self.call is not None:
|
||||||
|
self.call.cancel()
|
||||||
|
if force_call:
|
||||||
|
self()
|
||||||
|
else:
|
||||||
|
self._reschedule()
|
||||||
|
|
||||||
|
def next_call_time(self):
|
||||||
|
"""
|
||||||
|
Return the time in seconds until the next call. This takes
|
||||||
|
start_delay into account.
|
||||||
|
"""
|
||||||
|
currentTime = self.clock.seconds()
|
||||||
|
if self.start_delay is not None:
|
||||||
|
# take start_delay into account
|
||||||
|
untilNextTime = (self._lastTime - currentTime) % self.start_delay
|
||||||
|
return max(self._lastTime + self.start_delay, currentTime + untilNextTime)
|
||||||
|
else:
|
||||||
|
untilNextTime = (self._lastTime - currentTime) % self.interval
|
||||||
|
return max(self._lastTime + self.interval, currentTime + untilNextTime)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Base script, inherit from Script below instead.
|
# Base script, inherit from Script below instead.
|
||||||
#
|
#
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue