Switched Scripts to use ExtendedLoopingCall.
This commit is contained in:
parent
854a452f03
commit
9f2433b9c2
2 changed files with 61 additions and 102 deletions
|
|
@ -33,9 +33,9 @@ class BodyFunctions(Script):
|
||||||
a random check here so as to only return 33% of the time.
|
a random check here so as to only return 33% of the time.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if random.random() < 0.66:
|
#if random.random() < 0.66:
|
||||||
# no message this time
|
# # no message this time
|
||||||
return
|
# return
|
||||||
rand = random.random()
|
rand = random.random()
|
||||||
# return a random message
|
# return a random message
|
||||||
if rand < 0.1:
|
if rand < 0.1:
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,7 @@ scripts are inheriting from.
|
||||||
It also defines a few common scripts.
|
It also defines a few common scripts.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from time import time
|
from twisted.internet.defer import Deferred, 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,9 +22,6 @@ _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):
|
class ExtendedLoopingCall(LoopingCall):
|
||||||
"""
|
"""
|
||||||
LoopingCall that can start at a delay different
|
LoopingCall that can start at a delay different
|
||||||
|
|
@ -52,10 +48,12 @@ class ExtendedLoopingCall(LoopingCall):
|
||||||
if interval < 0:
|
if interval < 0:
|
||||||
raise ValueError, "interval must be >= 0"
|
raise ValueError, "interval must be >= 0"
|
||||||
|
|
||||||
|
self.running = True
|
||||||
d = self.deferred = Deferred()
|
d = self.deferred = Deferred()
|
||||||
self.starttime = self.clock.seconds()
|
self.starttime = self.clock.seconds()
|
||||||
self._lastTime = self.starttime
|
self._expectNextCallAt = self.starttime
|
||||||
self.interval = interval
|
self.interval = interval
|
||||||
|
self._runAtStart = now
|
||||||
|
|
||||||
if repeats and repeats > 0:
|
if repeats and repeats > 0:
|
||||||
self.repeats = int(repeats)
|
self.repeats = int(repeats)
|
||||||
|
|
@ -92,20 +90,6 @@ class ExtendedLoopingCall(LoopingCall):
|
||||||
self.start_delay = None
|
self.start_delay = None
|
||||||
super(ExtendedLoopingCall, self)._reschedule()
|
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):
|
def next_call_time(self):
|
||||||
"""
|
"""
|
||||||
|
|
@ -113,20 +97,13 @@ class ExtendedLoopingCall(LoopingCall):
|
||||||
start_delay into account.
|
start_delay into account.
|
||||||
"""
|
"""
|
||||||
currentTime = self.clock.seconds()
|
currentTime = self.clock.seconds()
|
||||||
if self.start_delay is not None:
|
return self._expectNextCallAt - currentTime
|
||||||
# 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.
|
||||||
#
|
#
|
||||||
class ScriptClass(TypeClass):
|
class ScriptBase(TypeClass):
|
||||||
"""
|
"""
|
||||||
Base class for scripts. Don't inherit from this, inherit
|
Base class for scripts. Don't inherit from this, inherit
|
||||||
from the class 'Script' instead.
|
from the class 'Script' instead.
|
||||||
|
|
@ -143,31 +120,31 @@ class ScriptClass(TypeClass):
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _start_task(self, start_now=True):
|
def _start_task(self):
|
||||||
"start task runner"
|
"start task runner"
|
||||||
|
|
||||||
self.ndb.twisted_task = LoopingCall(self._step_task)
|
self.ndb._task = ExtendedLoopingCall(self._step_task)
|
||||||
|
|
||||||
if self.ndb._paused_time:
|
if self.ndb._paused_time:
|
||||||
# we had paused the script, restarting
|
# the script was paused; restarting
|
||||||
#print " start with paused time:", self.key, self.ndb._paused_time
|
self.ndb._task.start(self.dbobj.db_interval,
|
||||||
self.ndb.twisted_task.start(self.ndb._paused_time, now=False)
|
now=False,
|
||||||
|
start_delay=self.ndb._paused_time,
|
||||||
|
repeats=self.dbobj.db_repeats)
|
||||||
|
del self.ndb._paused_time
|
||||||
else:
|
else:
|
||||||
# starting script anew.
|
# starting script anew
|
||||||
#print "_start_task: self.interval:", self.key, self.dbobj.interval
|
self.ndb._task.start(self.dbobj.db_interval,
|
||||||
self.ndb.twisted_task.start(self.dbobj.interval,
|
now=self.dbobj.db_start_delay,
|
||||||
now=start_now and not self.start_delay)
|
repeats=self.dbobj.db_repeats)
|
||||||
self.ndb.time_last_called = int(time())
|
|
||||||
|
|
||||||
def _stop_task(self):
|
def _stop_task(self):
|
||||||
"stop task runner"
|
"stop task runner"
|
||||||
try:
|
task = self.ndb._task
|
||||||
#print "stopping twisted task:", id(self.ndb.twisted_task), self.obj
|
if task and task.running:
|
||||||
if self.ndb.twisted_task and self.ndb.twisted_task.running:
|
task.stop()
|
||||||
self.ndb.twisted_task.stop()
|
|
||||||
except Exception:
|
|
||||||
logger.log_trace()
|
|
||||||
|
|
||||||
def _step_err_callback(self, e):
|
def _step_errback(self, e):
|
||||||
"callback for runner errors"
|
"callback for runner errors"
|
||||||
cname = self.__class__.__name__
|
cname = self.__class__.__name__
|
||||||
estring = _("Script %(key)s(#%(dbid)i) of type '%(cname)s': at_repeat() error '%(err)s'.") % \
|
estring = _("Script %(key)s(#%(dbid)i) of type '%(cname)s': at_repeat() error '%(err)s'.") % \
|
||||||
|
|
@ -179,38 +156,27 @@ class ScriptClass(TypeClass):
|
||||||
pass
|
pass
|
||||||
logger.log_errmsg(estring)
|
logger.log_errmsg(estring)
|
||||||
|
|
||||||
def _step_succ_callback(self):
|
def _step_callback(self):
|
||||||
"step task runner. No try..except needed due to defer wrap."
|
"step task runner. No try..except needed due to defer wrap."
|
||||||
|
|
||||||
if not self.is_valid():
|
if not self.is_valid():
|
||||||
self.stop()
|
self.stop()
|
||||||
return
|
return
|
||||||
self.at_repeat()
|
|
||||||
repeats = self.dbobj.db_repeats
|
|
||||||
if repeats <= 0:
|
|
||||||
pass # infinite repeat
|
|
||||||
elif repeats == 1:
|
|
||||||
self.stop()
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.dbobj.db_repeats -= 1
|
|
||||||
self.ndb.time_last_called = int(time())
|
|
||||||
self.save()
|
|
||||||
|
|
||||||
if self.ndb._paused_time:
|
# call hook
|
||||||
# this means we were running an unpaused script, for the
|
self.at_repeat()
|
||||||
# time remaining after the pause. Now we start a normal-running
|
|
||||||
# timer again.
|
repeats = self.ndb._task.repeats
|
||||||
# print "switching to normal run:", self.key
|
if repeats is not None:
|
||||||
del self.ndb._paused_time
|
if repeats <= 0:
|
||||||
self._stop_task()
|
self.stop()
|
||||||
self._start_task(start_now=False)
|
else:
|
||||||
|
self.dbobj.repeats = repeats
|
||||||
|
|
||||||
def _step_task(self):
|
def _step_task(self):
|
||||||
"step task"
|
"step task"
|
||||||
try:
|
try:
|
||||||
d = maybeDeferred(self._step_succ_callback)
|
return maybeDeferred(self._step_callback).addErrback(self._step_errback)
|
||||||
d.addErrback(self._step_err_callback)
|
|
||||||
return d
|
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
|
|
||||||
|
|
@ -224,14 +190,12 @@ class ScriptClass(TypeClass):
|
||||||
system; it's only here for the user to be able to
|
system; it's only here for the user to be able to
|
||||||
check in on their scripts and when they will next be run.
|
check in on their scripts and when they will next be run.
|
||||||
"""
|
"""
|
||||||
try:
|
task = self.ndb._task
|
||||||
if self.ndb._paused_time:
|
if task:
|
||||||
return max(0, (self.ndb.time_last_called + self.ndb._paused_time) - int(time()))
|
return int(task.next_call_time())
|
||||||
else:
|
|
||||||
return max(0, (self.ndb.time_last_called + self.dbobj.db_interval) - int(time()))
|
|
||||||
except Exception:
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def start(self, force_restart=False):
|
def start(self, force_restart=False):
|
||||||
"""
|
"""
|
||||||
Called every time the script is started (for
|
Called every time the script is started (for
|
||||||
|
|
@ -243,6 +207,7 @@ class ScriptClass(TypeClass):
|
||||||
returns 0 or 1 to indicated the script has been started or not.
|
returns 0 or 1 to indicated the script has been started or not.
|
||||||
Used in counting.
|
Used in counting.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
#print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj),
|
#print "Script %s (%s) start (active:%s, force:%s) ..." % (self.key, id(self.dbobj),
|
||||||
# self.is_active, force_restart)
|
# self.is_active, force_restart)
|
||||||
|
|
||||||
|
|
@ -292,12 +257,7 @@ class ScriptClass(TypeClass):
|
||||||
self.at_stop()
|
self.at_stop()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
if self.dbobj.db_interval > 0:
|
|
||||||
try:
|
|
||||||
self._stop_task()
|
self._stop_task()
|
||||||
except Exception:
|
|
||||||
logger.log_trace("Stopping script %s(%s)" % (self.key, self.dbid))
|
|
||||||
pass
|
|
||||||
try:
|
try:
|
||||||
self.dbobj.delete()
|
self.dbobj.delete()
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
|
|
@ -310,9 +270,9 @@ class ScriptClass(TypeClass):
|
||||||
This stops a running script and stores its active state.
|
This stops a running script and stores its active state.
|
||||||
"""
|
"""
|
||||||
#print "pausing", self.key, self.time_until_next_repeat()
|
#print "pausing", self.key, self.time_until_next_repeat()
|
||||||
dt = self.time_until_next_repeat()
|
task = self.ndb._task
|
||||||
if dt is None:
|
if task:
|
||||||
return
|
dt = self.ndb._task.next_call_time()
|
||||||
self.db._paused_time = dt
|
self.db._paused_time = dt
|
||||||
self._stop_task()
|
self._stop_task()
|
||||||
|
|
||||||
|
|
@ -322,18 +282,17 @@ class ScriptClass(TypeClass):
|
||||||
"""
|
"""
|
||||||
#print "unpausing", self.key, self.db._paused_time
|
#print "unpausing", self.key, self.db._paused_time
|
||||||
dt = self.db._paused_time
|
dt = self.db._paused_time
|
||||||
if dt is None:
|
if dt:
|
||||||
return False
|
|
||||||
try:
|
|
||||||
self.dbobj.is_active = True
|
|
||||||
self.at_start()
|
|
||||||
self.ndb._paused_time = dt
|
self.ndb._paused_time = dt
|
||||||
self._start_task(start_now=False)
|
|
||||||
del self.db._paused_time
|
del self.db._paused_time
|
||||||
|
self.dbobj.is_active = True
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.at_start()
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_trace()
|
logger.log_trace()
|
||||||
self.dbobj.is_active = False
|
|
||||||
return False
|
self._start_task()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# hooks
|
# hooks
|
||||||
|
|
@ -366,7 +325,7 @@ class ScriptClass(TypeClass):
|
||||||
# Base Script - inherit from this
|
# Base Script - inherit from this
|
||||||
#
|
#
|
||||||
|
|
||||||
class Script(ScriptClass):
|
class Script(ScriptBase):
|
||||||
"""
|
"""
|
||||||
This is the class you should inherit from, it implements
|
This is the class you should inherit from, it implements
|
||||||
the hooks called by the script machinery.
|
the hooks called by the script machinery.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue