-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtasks_logic.py
More file actions
121 lines (91 loc) · 4.04 KB
/
Copy pathtasks_logic.py
File metadata and controls
121 lines (91 loc) · 4.04 KB
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
import threading
import time
import json as js
import unicodedata
from pprint import pprint
def get_reverse(incoming_edges):
""" Return a dictionary of the reverse of the dependency
dictionary. The returned dictionary has key that
represents is a dependency of the tasks in the list value """
rev_json = {}
for key, val in incoming_edges.items():
for node in val:
rev_json[node] = rev_json.get(node, []) + [key]
for key in incoming_edges: # For tasks that gets rid of no dependencies
if key not in rev_json:
rev_json[key] = []
return rev_json
def get_nondependent_task_ids(incoming_edges):
""" Return a list of tasks with no dependencies """
S = []
for key, val in incoming_edges.items():
if not val:
S.append(key)
return S
def get_dependencies(json_string):
""" Return a dictionary of tasks and their
dependencies as defined in the json file """
d = js.loads(json_string)['tasks']
all_dependencies = {} # Maps tasaks to their dependencies
for task in d:
dependencies = task['dependencies']
key = task['id']
all_dependencies[key] = dependencies
return all_dependencies
def get_runtimes(json_string):
""" Return a dictionary of task ids and their
runtimes as defined in the json file """
d = js.loads(json_string)['tasks']
all_runtimes = {}
for task in d:
all_runtimes[task['id']] = task['runtime']
return all_runtimes
def tasks_satisfied_dependencies(json_string):
""" Return a dictionary of task ids that haven't
yet satisfied its dependencies """
all_tasks = js.loads(json_string)['tasks']
tasks_unsatisfied = {}
for task in all_tasks:
tasks_unsatisfied[task['id']] = False
return tasks_unsatisfied
def get_tasks_order():
""" Calculate the order in which tasks should be excecuted based
on their runtime and dependencies """
current_task = no_incoming_edges.pop(0)
if not all_dependencies[current_task] and satisfied[current_task]:
order_of_nodes.append(unicodedata.normalize('NFKD', current_task).encode('ascii','ignore'))
print "Running task " + current_task + " with runtime " + str(all_runtimes[current_task])
time.sleep(all_runtimes[current_task])
for neighbour in dependencies_to_remove[current_task]: # We remove all dependencies for future tasks
all_dependencies[neighbour].remove(current_task) # We remove a dependency
if not all_dependencies[neighbour]: # all dependencies satisfied (removed)
if neighbour not in no_incoming_edges:
no_incoming_edges.append(neighbour)
satisfied[neighbour] = True
new_task_thread = threading.Thread(target=get_tasks_order)
new_task_thread.start()
threads.append(new_task_thread)
time.sleep(0)
print "------------------------------> Finished running task " + current_task
if __name__ == "__main__":
s = open("tasks.json", 'r').read()
all_dependencies = get_dependencies(s) # task -> dependencies
all_runtimes = get_runtimes(s) # tasks -> runtimes (an integer value)
dependencies_to_remove = get_reverse(all_dependencies) # tasks that remove their dependencies
no_incoming_edges = get_nondependent_task_ids(all_dependencies) # starts as tasks that have no dependencies
satisfied = tasks_satisfied_dependencies(s)
# set all tasks with no dependencies to satisfied ie no dependencies
for task in no_incoming_edges:
satisfied[task] = True
order_of_nodes = []
threads = []
# parallelize the first tasks with no dependencies.
# once those tasks remove themselves from other tasks that depend on them,
# the next tasks get a thread called on them
while no_incoming_edges:
task_thread = threading.Thread(target=get_tasks_order)
task_thread.start()
threads.append(task_thread)
for thread in threads:
thread.join()
print order_of_nodes