Adding TaskRunnerThread class, for threaded operations, along with errorOccurred and elapsedTime methods for getting information about a process.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@40968 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -16,11 +16,12 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
import select
|
import select
|
||||||
import fcntl
|
import time
|
||||||
|
|
||||||
from subprocess import Popen, PIPE, STDOUT
|
from subprocess import Popen, PIPE, STDOUT
|
||||||
|
|
||||||
|
|
||||||
__all__ = ["Job", "Task", "TaskRunner"]
|
__all__ = ["Job", "Task", "TaskRunner", "TaskRunnerThread"]
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -58,22 +59,28 @@ class Job(object):
|
|||||||
|
|
||||||
LOGBASE="."
|
LOGBASE="."
|
||||||
|
|
||||||
def __init__(self, label, command, args=[], env=os.environ):
|
def __init__(self, label, command, args=[], env=os.environ, verbose=True):
|
||||||
self.label = label
|
self.label = label
|
||||||
self.command = command
|
self.command = command
|
||||||
self.args = args
|
self.args = args
|
||||||
self.env = env
|
self.env = env
|
||||||
self.proc = None
|
self.proc = None
|
||||||
if self.label:
|
self.startTime = None
|
||||||
if not os.path.exists(self.LOGBASE):
|
self.stopTime = None
|
||||||
os.makedirs(self.LOGBASE)
|
self.verbose = verbose
|
||||||
self.log = file("%s/%s.log" % (self.LOGBASE, label), "w", 0)
|
self.label = label
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.proc = Popen([self.command] + self.args, # the command and args to execute
|
self.proc = Popen([self.command] + self.args, # the command and args to execute
|
||||||
stdout=PIPE, stderr=STDOUT, env=self.env,
|
stdout=PIPE, stderr=STDOUT, env=self.env,
|
||||||
bufsize=0 # line-buffered
|
bufsize=0 # line-buffered
|
||||||
)
|
)
|
||||||
|
self.startTime = time.time()
|
||||||
|
if self.label:
|
||||||
|
if not os.path.exists(self.LOGBASE):
|
||||||
|
os.makedirs(self.LOGBASE)
|
||||||
|
self.log = file("%s/%s.log" % (self.LOGBASE, self.label), "w", 0)
|
||||||
|
|
||||||
# put the file in non-blocking mode
|
# put the file in non-blocking mode
|
||||||
#flags = fcntl.fcntl (self.proc.stdout, fcntl.F_GETFL, 0)
|
#flags = fcntl.fcntl (self.proc.stdout, fcntl.F_GETFL, 0)
|
||||||
#flags = flags | os.O_NONBLOCK
|
#flags = flags | os.O_NONBLOCK
|
||||||
@@ -84,6 +91,7 @@ class Job(object):
|
|||||||
if self.proc is not None and self.proc.returncode is None:
|
if self.proc is not None and self.proc.returncode is None:
|
||||||
os.kill(self.proc.pid, signal.SIGTERM)
|
os.kill(self.proc.pid, signal.SIGTERM)
|
||||||
self.logLines()
|
self.logLines()
|
||||||
|
self.stopTime = time.time()
|
||||||
|
|
||||||
|
|
||||||
def fileno(self):
|
def fileno(self):
|
||||||
@@ -92,6 +100,15 @@ class Job(object):
|
|||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
|
def elapsedTime(self):
|
||||||
|
now = self.stopTime
|
||||||
|
if not now:
|
||||||
|
now = time.time()
|
||||||
|
elapsed_time = now-self.startTime
|
||||||
|
mins = elapsed_time/60
|
||||||
|
hours = mins/60
|
||||||
|
seconds = (elapsed_time - mins) % 60
|
||||||
|
return "%d:%d:%d" % (hours, mins, seconds)
|
||||||
|
|
||||||
def logLines(self):
|
def logLines(self):
|
||||||
if self.proc is not None:
|
if self.proc is not None:
|
||||||
@@ -101,6 +118,7 @@ class Job(object):
|
|||||||
if self.label:
|
if self.label:
|
||||||
self.log.write(line)
|
self.log.write(line)
|
||||||
line = "** %s: %s" % (self.label, line)
|
line = "** %s: %s" % (self.label, line)
|
||||||
|
if self.verbose:
|
||||||
sys.stdout.write(line)
|
sys.stdout.write(line)
|
||||||
|
|
||||||
|
|
||||||
@@ -167,16 +185,26 @@ class Task(object):
|
|||||||
|
|
||||||
class TaskRunner(object):
|
class TaskRunner(object):
|
||||||
"""
|
"""
|
||||||
Manages the running of multiple tasks.
|
Manages the running of multiple tasks. Name can be used to identify
|
||||||
|
a specific TaskRunner instance when reporting information back to the user.
|
||||||
"""
|
"""
|
||||||
def __init__(self, tasks=[]):
|
def __init__(self, tasks=[], name="TaskRunner Tasks"):
|
||||||
if type(tasks) != list:
|
if type(tasks) != list:
|
||||||
tasks = [tasks]
|
tasks = [tasks]
|
||||||
self.tasks = tasks[:]
|
self.tasks = tasks[:]
|
||||||
|
self.name = name
|
||||||
|
self.rc = 0
|
||||||
|
|
||||||
def append(self, task):
|
def append(self, task):
|
||||||
self.tasks.append(task)
|
self.tasks.append(task)
|
||||||
|
|
||||||
|
def errorOccurred(self):
|
||||||
|
"""
|
||||||
|
Only used for threaded TR instances. Once all TR tasks have completed,
|
||||||
|
we'll want to check to make sure there were no errors in the process.
|
||||||
|
"""
|
||||||
|
return self.rc != 0
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
# start all the active jobs
|
# start all the active jobs
|
||||||
for task in self.tasks:
|
for task in self.tasks:
|
||||||
@@ -202,6 +230,7 @@ class TaskRunner(object):
|
|||||||
if job.returnCode() != 0:
|
if job.returnCode() != 0:
|
||||||
rc = job.returnCode()
|
rc = job.returnCode()
|
||||||
print "JOB RETURNED FAILURE CODE! (%d)" % rc
|
print "JOB RETURNED FAILURE CODE! (%d)" % rc
|
||||||
|
self.rc = rc
|
||||||
self.stopAllJobs()
|
self.stopAllJobs()
|
||||||
return rc
|
return rc
|
||||||
else:
|
else:
|
||||||
@@ -225,26 +254,60 @@ class TaskRunner(object):
|
|||||||
if job:
|
if job:
|
||||||
job.stop()
|
job.stop()
|
||||||
|
|
||||||
|
|
||||||
|
import threading
|
||||||
|
|
||||||
|
class TaskRunnerThread(threading.Thread):
|
||||||
|
def __init__(self, taskRunner, callback=None):
|
||||||
|
self.taskRunner = taskRunner
|
||||||
|
self.startTime = None
|
||||||
|
self.stopTime = None
|
||||||
|
self.callback = callback
|
||||||
|
threading.Thread.__init__ ( self )
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.startTime = time.time()
|
||||||
|
self.taskRunner.run()
|
||||||
|
self.stopTime = time.time()
|
||||||
|
#if self.callback:
|
||||||
|
# self.callback
|
||||||
|
|
||||||
|
def elapsedTime(self):
|
||||||
|
now = self.stopTime
|
||||||
|
if not now:
|
||||||
|
now = time.time()
|
||||||
|
elapsed_time = now-self.startTime
|
||||||
|
mins = elapsed_time/60
|
||||||
|
hours = mins/60
|
||||||
|
seconds = (elapsed_time - mins) % 60
|
||||||
|
return "%d:%d:%d" % (hours, mins, seconds)
|
||||||
|
|
||||||
|
def totalTime(self):
|
||||||
|
if self.stopTime:
|
||||||
|
return self.elapsedTime()
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
||||||
j1 = Job("label1", ["./tmp/job-1.py", "TEST-1"])
|
j1 = Job("label1", "./tmp/job-1.py", ["TEST-1"])
|
||||||
j2 = Job("label2", ["./tmp/job-2.sh", "TEST-2"])
|
j2 = Job("label2", "./tmp/job-2.sh", ["TEST-2"])
|
||||||
|
|
||||||
t1 = Task()
|
t1 = Task()
|
||||||
t1.append(j1)
|
t1.append(j1)
|
||||||
t1.append(j2)
|
t1.append(j2)
|
||||||
|
|
||||||
j3 = Job("task2a", ["./tmp/job-1.py", "TASK-2a"])
|
j3 = Job("task2a", "./tmp/job-1.py", ["TASK-2a"])
|
||||||
j4 = Job("task2b", ["./tmp/job-2.sh", "TASK-2b"])
|
j4 = Job("task2b", "./tmp/job-2.sh", ["TASK-2b"])
|
||||||
|
|
||||||
t2 = Task()
|
t2 = Task()
|
||||||
t2.append(j4)
|
t2.append(j4)
|
||||||
t2.append(j3)
|
t2.append(j3)
|
||||||
|
|
||||||
t3 = Task([Job("error", ["./tmp/job-3.sh", "TASK-3"])])
|
t3 = Task([Job("error", "./tmp/job-3.sh", ["TASK-3"])])
|
||||||
|
|
||||||
tr = TaskRunner()
|
tr = TaskRunner()
|
||||||
tr.append(t1)
|
tr.append(t1)
|
||||||
|
Reference in New Issue
Block a user