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:
Kevin Ollivier
2006-09-02 22:00:06 +00:00
parent 8c9c423bea
commit 3a6e98206b

View File

@@ -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)