Mercurial > hg > config
comparison python/multiproc.py @ 611:8e23bbc9c197
STUB: python/multiproc.py
author | Jeff Hammel <k0scist@gmail.com> |
---|---|
date | Sun, 02 Feb 2014 15:32:29 -0800 |
parents | 5ce25399da67 |
children | 839dfd35d567 |
comparison
equal
deleted
inserted
replaced
610:5ce25399da67 | 611:8e23bbc9c197 |
---|---|
16 class Process(subprocess.Popen): | 16 class Process(subprocess.Popen): |
17 """why would you name a subprocess object Popen?""" | 17 """why would you name a subprocess object Popen?""" |
18 | 18 |
19 # http://docs.python.org/2/library/subprocess.html#popen-constructor | 19 # http://docs.python.org/2/library/subprocess.html#popen-constructor |
20 defaults = {'bufsize': 1, # line buffered | 20 defaults = {'bufsize': 1, # line buffered |
21 'store_output': True, # store stdout | |
21 } | 22 } |
22 | 23 |
23 def __init__(self, command, **kwargs): | 24 def __init__(self, command, **kwargs): |
24 | 25 |
25 # setup arguments | 26 # setup arguments |
31 # type of command (string or list) | 32 # type of command (string or list) |
32 if not subprocess.mswindows: | 33 if not subprocess.mswindows: |
33 _kwargs['shell'] = isinstance(command, string) | 34 _kwargs['shell'] = isinstance(command, string) |
34 | 35 |
35 # output buffer | 36 # output buffer |
37 self.location = 0 | |
36 self.output_buffer = tempfile.SpooledTemporaryFile() | 38 self.output_buffer = tempfile.SpooledTemporaryFile() |
37 self.location = 0 | 39 self.output = '' if _kwargs.pop('store_output') else None |
38 self.output = '' | |
39 _kwargs['stdout'] = self.output_buffer | 40 _kwargs['stdout'] = self.output_buffer |
40 | 41 |
42 # runtime | |
43 self.start = time.time() | |
44 self.end = None | |
45 | |
41 # launch subprocess | 46 # launch subprocess |
42 self.start = time.time() | |
43 subprocess.Popen.__init__(self, command, **_kwargs) | 47 subprocess.Popen.__init__(self, command, **_kwargs) |
44 | 48 |
45 def wait(self, maxtime=None, sleep=1.): | 49 def _finalize(self, process_output): |
50 """internal function to finalize""" | |
51 | |
52 # read final output | |
53 self.read(process_output) | |
54 | |
55 # reset output buffer | |
56 self.output_buffer.seek(0) | |
57 | |
58 # set end time | |
59 self.end = time.time() | |
60 | |
61 def wait(self, maxtime=None, sleep=1., process_output=None): | |
46 """ | 62 """ |
47 maxtime -- timeout in seconds | 63 maxtime -- timeout in seconds |
48 sleep -- number of seconds to sleep between polling | 64 sleep -- number of seconds to sleep between polling |
49 """ | 65 """ |
50 while self.poll() is None: | 66 while self.poll() is None: |
51 | 67 |
52 # check for timeout | 68 # check for timeout |
53 curr_time = time.time() | 69 curr_time = time.time() |
54 run_time = curr_time - self.start | 70 run_time = curr_time - self.start |
55 if run_time > maxtime: | 71 if run_time > maxtime: |
56 # TODO: read from output | 72 self.kill() |
57 return process.kill() | 73 self._finalize(process_output) |
74 return | |
58 | 75 |
59 # read from output buffer | 76 # read from output buffer |
60 read = self.read() | 77 self.read(process_output) |
61 | 78 |
62 # naptime | 79 # naptime |
63 if sleep: | 80 if sleep: |
64 time.sleep(sleep) | 81 time.sleep(sleep) |
65 | 82 |
66 # reset tempfile | 83 # finalize |
67 output.seek(0) | 84 self._finalize() |
68 | 85 |
69 return self.returncode # set by ``.poll()`` | 86 return self.returncode # set by ``.poll()`` |
70 | 87 |
71 def read(self): | 88 def read(self, process_output=None): |
72 """read from the output buffer""" | 89 """read from the output buffer""" |
90 | |
73 self.output_buffer.seek(self.location) | 91 self.output_buffer.seek(self.location) |
74 read = self.output_buffer.read() | 92 read = self.output_buffer.read() |
75 self.output += read | 93 if self.output is not None: |
94 self.output += read | |
95 if process_output: | |
96 process_output(read) | |
76 self.location += len(read) | 97 self.location += len(read) |
77 return read | 98 return read |
78 | 99 |
79 def commandline(self): | 100 def commandline(self): |
80 """returns string of command line""" | 101 """returns string of command line""" |
83 return self.command | 104 return self.command |
84 return subprocess.list2cmdline(self.command) | 105 return subprocess.list2cmdline(self.command) |
85 | 106 |
86 __str__ = commandline | 107 __str__ = commandline |
87 | 108 |
109 def runtime(self): | |
110 """returns time spent running or total runtime if completed""" | |
111 | |
112 if self.end is None: | |
113 return self.end - self.start | |
114 return time.time() - self.start | |
115 | |
88 | 116 |
89 def main(args=sys.argv[1:]): | 117 def main(args=sys.argv[1:]): |
90 """CLI""" | 118 """CLI""" |
91 | 119 |
92 # available programs | 120 # available programs |
93 progs = {'yes': ["yes"], | 121 progs = {'yes': ["yes"], |
94 'ping': ['ping', 'google.com']} | 122 'ping': ['ping', 'google.com']} |
95 | 123 |
96 | |
97 # parse command line | 124 # parse command line |
98 usage = '%prog [options]' | 125 parser = argparse.ArgumentParser(description=__doc__) |
99 parser = argparse.ArgumentParser(usage=usage, description=__doc__) | |
100 parser.add_argument("-t", "--time", dest="time", | 126 parser.add_argument("-t", "--time", dest="time", |
101 type=float, default=4., | 127 type=float, default=4., |
102 help="seconds to run for") | 128 help="seconds to run for") |
103 parser.add_argument("-s", "--sleep", dest="sleep", | 129 parser.add_argument("-s", "--sleep", dest="sleep", |
104 type=float, default=1., | 130 type=float, default=1., |
118 sys.exit(0) | 144 sys.exit(0) |
119 | 145 |
120 # select program | 146 # select program |
121 prog = progs[options.program] | 147 prog = progs[options.program] |
122 | 148 |
149 # start process | |
123 proc = Process(prog) | 150 proc = Process(prog) |
151 | |
152 # callback for output processing | |
153 def process_output(output): | |
154 print output.upper() | |
124 | 155 |
125 # # start the main subprocess loop | 156 # # start the main subprocess loop |
126 # # TODO -> OO | 157 # # TODO -> OO |
127 # output = tempfile.SpooledTemporaryFile() | 158 # output = tempfile.SpooledTemporaryFile() |
128 # start = time.time() | 159 # start = time.time() |
141 # time.sleep(options.sleep) | 172 # time.sleep(options.sleep) |
142 | 173 |
143 # # reset tempfile | 174 # # reset tempfile |
144 # output.seek(0) | 175 # output.seek(0) |
145 | 176 |
146 n_lines = len(output.read().splitlines()) | 177 # wait for being done |
178 proc.wait(maxtime=options.time, sleep=options.sleep, process_output=process_output) | |
179 | |
180 # finalization | |
181 output = proc.output | |
182 n_lines = len(output.splitlines()) | |
147 print ("{}: {} lines".format(subprocess.list2cmdline(prog), n_lines)) | 183 print ("{}: {} lines".format(subprocess.list2cmdline(prog), n_lines)) |
148 | 184 |
149 if __name__ == '__main__': | 185 if __name__ == '__main__': |
150 main() | 186 main() |