def scheduler(tasks: Dict[Source, Task],
task_queue: TaskQueue,
result_queue: ResultQueue,
tree: TaskTree,
hashes: Dict[Filename, Hash],
changed_files: List[Source]) -> None:
"""Schedule tasks and handle compiled tasks."""
start = time.time()
n_all_lines = sum(tree.line_nums[src] for src in changed_files)
n_lines = 0
waiting = set(changed_files)
scheduled: Set[Source] = set()
while True:
blocking = waiting | scheduled
for src in list(waiting):
if not (blocking & tree.ancestors[src]):
hashes.pop(src, None) # if compilation gets interrupted
task_queue.put_nowait((
-tree.priority[src],
src,
Args(tasks[src].args + (str(tasks[src].source),))
))
scheduled.add(src)
waiting.remove(src)
sys.stdout.write(
f' Progress: {len(waiting)} waiting, {len(scheduled)} scheduled, '
f'{n_lines}/{n_all_lines} lines ({100*n_lines/n_all_lines:.1f}%), '
f'ETA: {(time.time()-start)*n_all_lines/(n_lines or nan):.1f} s\r'
)
sys.stdout.flush()
if not blocking:
break
src, retcode, clock = await result_queue.get()
if retcode != 0:
raise CompilationError(src, retcode)
clocks.append((src, clock, tree.line_nums[src]))
hashes[src] = tree.hashes[src]
n_lines += tree.line_nums[src]
scheduled.remove(src)
pprint(f'Compiled {src}.')
for mod in tree.src_mods[src]:
modfile = mod + '.mod'
modhash = get_hash(Path(modfile))
if modhash != hashes.get(modfile):
hashes[modfile] = modhash
for src in tree.mod_uses[mod]:
assert src not in scheduled
hashes.pop(src, None)
if src not in waiting:
n_all_lines += tree.line_nums[src]
waiting.add(src)
评论列表
文章目录