-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathTaskHandler.py
139 lines (107 loc) · 3.87 KB
/
TaskHandler.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from time import time
from threading import Thread
class TaskHandler(object):
"""The task handler.
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 = False
self._suspend = False
self._lastTime = None
self._startTime = start
self._registerTime = time()
self._reregister = True
self._rerun = False
self._period = abs(period)
self._isOnDemand = False
## Scheduling ##
def reset(self, start, period, task, reregister):
self._startTime = start
self._period = abs(period)
self._task = task
self._reregister = reregister
def runTask(self):
"""Run this task in a background thread."""
if self._suspend:
self._scheduler.notifyCompletion(self)
return
self._rerun = False
self._thread = Thread(None, self._task._run, self.name(), (self,))
self._isRunning = True
self._thread.start()
def reschedule(self):
"""Determine whether this task should be rescheduled.
Increments the startTime and returns true if this is
a periodically executed task.
"""
if self._period == 0 or not self._reregister:
return False
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._period
return True
def notifyCompletion(self):
self._isRunning = False
self._lastTime = time()
self._scheduler.notifyCompletion(self)
def notifyFailure(self):
self._isRunning = False
self._lastTime = time()
self._scheduler.notifyFailure(self)
## Attributes ##
def isRunning(self):
return self._isRunning
def runAgain(self):
"""Determine whether this task should be run again.
This method lets the Scheduler check to see whether this task should be
re-run when it terminates.
"""
return self._rerun
def isOnDemand(self):
"""Return True if this task is not scheduled for periodic execution."""
return self._isOnDemand
def setOnDemand(self, onDemand=True):
self._isOnDemand = bool(onDemand)
def runOnCompletion(self):
"""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 = True
def unregister(self):
"""Request that this task not be kept after its current completion.
Used to remove a task from the scheduler.
"""
self._reregister = False
self._rerun = False
def disable(self):
"""Disable future invocations of this task."""
self._suspend = True
def enable(self):
"""Enable future invocations of this task."""
self._suspend = False
def period(self):
"""Return the period of this task."""
return self._period
def setPeriod(self, period):
"""Change the period for this task."""
self._period = period
def stop(self):
self._isRunning = False
def name(self):
return self._name
def startTime(self, newTime=None):
if newTime:
self._startTime = newTime
return self._startTime