Mercurial > lcfOS
comparison python/ppci/tasks.py @ 342:86b02c98a717 devel
Moved target directory
author | Windel Bouwman |
---|---|
date | Sat, 01 Mar 2014 15:40:31 +0100 |
parents | 6f4753202b9a |
children | 3bb7dcfe5529 |
comparison
equal
deleted
inserted
replaced
341:4d204f6f7d4e | 342:86b02c98a717 |
---|---|
1 """ | |
2 This module defines tasks and a runner for these tasks. Tasks can | |
3 have dependencies and it can be determined if they need to be run. | |
4 """ | |
1 | 5 |
2 import logging | 6 import logging |
3 | 7 |
4 class TaskError(Exception): | 8 class TaskError(Exception): |
5 pass | 9 pass |
7 | 11 |
8 class Task: | 12 class Task: |
9 """ Task that can run, and depend on other tasks """ | 13 """ Task that can run, and depend on other tasks """ |
10 def __init__(self, name): | 14 def __init__(self, name): |
11 self.name = name | 15 self.name = name |
12 self.subtasks = [] | |
13 self.completed = False | 16 self.completed = False |
14 self.dependencies = [] | 17 self.dependencies = set() |
15 self.duration = 1 | 18 self.duration = 1 |
16 | 19 |
17 def run(self): | 20 def run(self): |
18 raise NotImplementedError("Implement this abstract method!") | 21 raise NotImplementedError("Implement this abstract method!") |
19 | 22 |
20 def fire(self): | 23 def fire(self): |
24 """ Wrapper around run that marks the task as done """ | |
21 assert all(t.completed for t in self.dependencies) | 25 assert all(t.completed for t in self.dependencies) |
22 self.run() | 26 self.run() |
23 self.completed = True | 27 self.completed = True |
24 | 28 |
25 def addSubTask(self, tsk): | 29 def add_dependency(self, task): |
26 self.subtasks.append(tsk) | 30 """ Add another task as a dependency for this task """ |
27 return tsk | 31 if task is self: |
32 raise TaskError('Can not add dependency on task itself!') | |
33 if self in task.down_stream_tasks: | |
34 raise TaskError('Can not introduce circular task') | |
35 self.dependencies.add(task) | |
36 return task | |
28 | 37 |
29 def addDependency(self, task): | 38 @property |
30 self.dependencies.append(task) | 39 def down_stream_tasks(self): |
31 return task | 40 """ Return a set of all tasks that follow this task """ |
41 # TODO: is this upstream or downstream??? | |
42 cdst = list(dep.down_stream_tasks for dep in self.dependencies) | |
43 cdst.append(self.dependencies) | |
44 return set.union(*cdst) | |
45 | |
46 def __gt__(self, other): | |
47 return other in self.down_stream_tasks | |
32 | 48 |
33 def __repr__(self): | 49 def __repr__(self): |
34 return 'Task "{}"'.format(self.name) | 50 return 'Task "{}"'.format(self.name) |
51 | |
52 | |
53 class EmptyTask(Task): | |
54 """ Basic task that does nothing """ | |
55 def run(self): | |
56 pass | |
35 | 57 |
36 | 58 |
37 class TaskRunner: | 59 class TaskRunner: |
38 """ Basic task runner that can run some tasks in sequence """ | 60 """ Basic task runner that can run some tasks in sequence """ |
39 def __init__(self): | 61 def __init__(self): |
46 @property | 68 @property |
47 def total_duration(self): | 69 def total_duration(self): |
48 return sum(t.duration for t in self.task_list) | 70 return sum(t.duration for t in self.task_list) |
49 | 71 |
50 def run_tasks(self): | 72 def run_tasks(self): |
73 # First sort tasks: | |
74 self.task_list.sort() | |
75 | |
76 # Run tasks: | |
51 passed_time = 0.0 | 77 passed_time = 0.0 |
52 total_time = self.total_duration | 78 total_time = self.total_duration |
53 try: | 79 try: |
54 for t in self.task_list: | 80 for t in self.task_list: |
55 self.report_progress(passed_time / total_time, t.name) | 81 self.report_progress(passed_time / total_time, t.name) |
56 t.fire() | 82 t.fire() |
57 passed_time += t.duration | 83 passed_time += t.duration |
58 except TaskError as e: | 84 except TaskError as e: |
59 print('Error: {}'.format(e)) | 85 self.logger.error(str(e.msg)) |
60 return 1 | 86 return 1 |
61 self.report_progress(1, 'OK') | 87 self.report_progress(1, 'OK') |
62 return 0 | 88 return 0 |
63 | 89 |
64 def display(self): | 90 def display(self): |