mirror of
https://github.com/YosysHQ/sby.git
synced 2025-04-23 05:15:30 +00:00
Begin converting taskloop to use asyncio module.
Signed-off-by: William D. Jones <thor0505@comcast.net>
This commit is contained in:
parent
7bae1b8bba
commit
118280191a
1 changed files with 89 additions and 1 deletions
|
@ -20,6 +20,7 @@ import os, re, sys, signal
|
|||
if os.name == "posix":
|
||||
import resource, fcntl
|
||||
import subprocess
|
||||
import asyncio
|
||||
from shutil import copyfile, rmtree
|
||||
from select import select
|
||||
from time import time, localtime, sleep
|
||||
|
@ -200,6 +201,56 @@ class SbyTask:
|
|||
next_task.poll()
|
||||
return
|
||||
|
||||
async def output_async(self):
|
||||
while True:
|
||||
outs = await self.p.stdout.readline()
|
||||
await asyncio.sleep(0) # https://bugs.python.org/issue24532
|
||||
outs = outs.decode("utf-8")
|
||||
if len(outs) == 0: break
|
||||
if outs[-1] != '\n':
|
||||
self.linebuffer += outs
|
||||
break
|
||||
outs = (self.linebuffer + outs).strip()
|
||||
self.linebuffer = ""
|
||||
self.handle_output(outs)
|
||||
|
||||
async def maybe_spawn_async(self):
|
||||
if self.finished or self.terminated:
|
||||
return
|
||||
|
||||
if not self.running:
|
||||
for dep in self.deps:
|
||||
if not dep.finished:
|
||||
return
|
||||
|
||||
self.job.log("%s: starting process \"%s\"" % (self.info, self.cmdline))
|
||||
self.p = await asyncio.create_subprocess_shell(self.cmdline, stdin=asyncio.subprocess.DEVNULL,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=(asyncio.subprocess.STDOUT if self.logstderr else None))
|
||||
self.job.tasks_pending.remove(self)
|
||||
self.job.tasks_running.append(self)
|
||||
self.running = True
|
||||
asyncio.ensure_future(self.output_async())
|
||||
self.fut = asyncio.ensure_future(self.p.wait())
|
||||
|
||||
async def shutdown_and_notify_async(self):
|
||||
self.job.log("%s: finished (returncode=%d)" % (self.info, self.p.returncode))
|
||||
self.job.tasks_running.remove(self)
|
||||
self.running = False
|
||||
|
||||
self.handle_exit(self.p.returncode)
|
||||
|
||||
if self.checkretcode and self.p.returncode != 0:
|
||||
self.job.status = "ERROR"
|
||||
self.job.log("%s: job failed. ERROR." % self.info)
|
||||
self.terminated = True
|
||||
self.job.terminate()
|
||||
return
|
||||
|
||||
self.finished = True
|
||||
for next_task in self.notify:
|
||||
await next_task.maybe_spawn_async()
|
||||
return
|
||||
|
||||
class SbyAbort(BaseException):
|
||||
pass
|
||||
|
@ -283,6 +334,41 @@ class SbyJob:
|
|||
self.status = "TIMEOUT"
|
||||
self.terminate(timeout=True)
|
||||
|
||||
def taskloop_async(self):
|
||||
if os.name != "posix":
|
||||
loop = asyncio.ProactorEventLoop()
|
||||
asyncio.set_event_loop(loop)
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.set_debug(enabled=True)
|
||||
poll_fut = asyncio.ensure_future(self.task_poller())
|
||||
loop.run_until_complete(poll_fut)
|
||||
|
||||
async def task_poller(self):
|
||||
for task in self.tasks_pending:
|
||||
await task.maybe_spawn_async()
|
||||
|
||||
while len(self.tasks_running):
|
||||
task_futs = []
|
||||
for task in self.tasks_running:
|
||||
if task.running:
|
||||
task_futs.append(task.fut)
|
||||
(done, pending) = await asyncio.wait(task_futs, return_when=asyncio.FIRST_COMPLETED)
|
||||
|
||||
for task in self.tasks_running:
|
||||
if task.fut in done:
|
||||
await task.shutdown_and_notify_async()
|
||||
|
||||
# for task in self.tasks_pending:
|
||||
# await task.poll_async()
|
||||
|
||||
#if self.opt_timeout is not None:
|
||||
#total_clock_time = int(time() - self.start_clock_time)
|
||||
#if total_clock_time > self.opt_timeout:
|
||||
#self.log("Reached TIMEOUT (%d seconds). Terminating all tasks." % self.opt_timeout)
|
||||
#self.status = "TIMEOUT"
|
||||
#self.terminate(timeout=True)
|
||||
|
||||
|
||||
def log(self, logmessage):
|
||||
tm = localtime()
|
||||
print("SBY {:2d}:{:02d}:{:02d} [{}] {}".format(tm.tm_hour, tm.tm_min, tm.tm_sec, self.workdir, logmessage), flush=True)
|
||||
|
@ -655,7 +741,9 @@ class SbyJob:
|
|||
if opt not in self.used_options:
|
||||
self.error("Unused option: {}".format(opt))
|
||||
|
||||
self.taskloop()
|
||||
# self.taskloop()
|
||||
self.taskloop_async()
|
||||
|
||||
|
||||
total_clock_time = int(time() - self.start_clock_time)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue