from time import time, sleep from threading import Event, Thread class TaskHandler: """ While the Task class only knows what task to perform with the run()-method, the TaskHandler has all the knowledge about the periodicity of the task. Instances of this class are managed by the Scheduler in the scheduled, running and onDemand dictionaries. """ ## Init ## def __init__(self, scheduler, start, period, task, name): self._scheduler = scheduler self._task = task self._name = name self._thread = None self._isRunning = 0 self._suspend = 0 self._lastTime = None self._startTime = start self._registerTime = time() self._reregister = 1 self._rerun = 0 self._period = abs(period) ## Scheduling ## def reset(self, start, period, task, reregister): self._startTime = start self._period = abs(period) self._task = task self._reregister = reregister def runTask(self): """ Runs this task in a background thread. """ if self._suspend: self._scheduler.notifyCompletion(self) return self._rerun = 0 self._thread = Thread(None, self._task._run, self.name(), (self,)) self._isRunning = 1 self._thread.start() def reschedule(self): """ Method to determine whether this task should be rescheduled. Increments the startTime and returns true if this is a periodically executed task. """ if self._period == 0: return 0 else: if self._lastTime - self._startTime > self._period: #if the time taken to run the task exceeds the period self._startTime = self._lastTime + self._period else: self._startTime = self._startTime + self._period return 1 def notifyCompletion(self): self._isRunning = 0 self._lastTime = time() self._scheduler.notifyCompletion(self) ## Attributes ## def isRunning(self): return self._isRunning def runAgain(self): """ This method lets the Scheduler check to see whether this task should be re-run when it terminates """ return self._rerun def isOnDemand(self): """ Returns true if this task is not scheduled for periodic execution. """ return self._period == 1 def runOnCompletion(self): """ Method to request that this task be re-run after its current completion. Intended for on-demand tasks that are requested by the Scheduler while they are already running. """ self._rerun = 1 def unregister(self): """ Method to request that this task not be kept after its current completion. Used to remove a task from the scheduler """ self._reregister = 0 self._rerun = 0 def disable(self): """ Method to disable future invocations of this task. """ self._suspend = 1 def enable(self): """ Method to enable future invocations of this task. """ self._suspend = 0 def period(self): """ Returns the period of this task. """ return self._period def setPeriod(self, period): """ Mmethod to change the period for this task. """ self._period = period def stop(self): self._isRunning = 0 def name(self): return self._name def startTime(self, newTime=None): if newTime: self._startTime = newTime return self._startTime