334
|
1
|
|
2 import logging
|
329
|
3
|
|
4 class TaskError(Exception):
|
|
5 pass
|
|
6
|
|
7
|
|
8 class Task:
|
|
9 """ Task that can run, and depend on other tasks """
|
|
10 def __init__(self, name):
|
|
11 self.name = name
|
|
12 self.subtasks = []
|
|
13 self.completed = False
|
|
14 self.dependencies = []
|
334
|
15 self.duration = 1
|
329
|
16
|
|
17 def run(self):
|
|
18 raise NotImplementedError("Implement this abstract method!")
|
|
19
|
|
20 def fire(self):
|
|
21 assert all(t.completed for t in self.dependencies)
|
|
22 self.run()
|
|
23 self.completed = True
|
|
24
|
|
25 def addSubTask(self, tsk):
|
|
26 self.subtasks.append(tsk)
|
|
27 return tsk
|
|
28
|
|
29 def addDependency(self, task):
|
|
30 self.dependencies.append(task)
|
|
31 return task
|
|
32
|
332
|
33 def __repr__(self):
|
|
34 return 'Task "{}"'.format(self.name)
|
|
35
|
329
|
36
|
|
37 class TaskRunner:
|
332
|
38 """ Basic task runner that can run some tasks in sequence """
|
329
|
39 def __init__(self):
|
334
|
40 self.logger = logging.getLogger('taskrunner')
|
329
|
41 self.task_list = []
|
332
|
42
|
329
|
43 def add_task(self, task):
|
|
44 self.task_list.append(task)
|
|
45
|
334
|
46 @property
|
|
47 def total_duration(self):
|
|
48 return sum(t.duration for t in self.task_list)
|
|
49
|
329
|
50 def run_tasks(self):
|
334
|
51 passed_time = 0.0
|
|
52 total_time = self.total_duration
|
329
|
53 try:
|
|
54 for t in self.task_list:
|
334
|
55 self.report_progress(passed_time / total_time, t.name)
|
329
|
56 t.fire()
|
334
|
57 passed_time += t.duration
|
329
|
58 except TaskError as e:
|
|
59 print('Error: {}'.format(e))
|
|
60 return 1
|
334
|
61 self.report_progress(1, 'OK')
|
329
|
62 return 0
|
332
|
63
|
|
64 def display(self):
|
|
65 """ Display task how they would be run """
|
|
66 for task in self.task_list:
|
|
67 print(task)
|
334
|
68
|
|
69 def report_progress(self, percentage, text):
|
|
70 self.logger.info('[{:3.1%}] {}'.format(percentage, text))
|