annotate python/multiproc.py @ 606:5b561c7b2005

STUB: python/multiproc.py
author Jeff Hammel <k0scist@gmail.com>
date Sun, 02 Feb 2014 11:07:04 -0800
parents bd30deecdf4a
children 567492ef7b57
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
1 #!/usr/bin/env python
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
2
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
3 """
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
4 multiprocessing/subprocess experiments
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
5 """
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
6
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
7 import argparse
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
8 import os
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
9 import subprocess
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
10 import sys
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
11 import time
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
12 import tempfile
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
13
606
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
14 string = (str, unicode)
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
15
601
7f189613a289 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 600
diff changeset
16 class Process(subprocess.Popen):
7f189613a289 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 600
diff changeset
17 """why would you name a subprocess object Popen?"""
7f189613a289 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 600
diff changeset
18
606
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
19 # http://docs.python.org/2/library/subprocess.html#popen-constructor
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
20 defaults = {'buffsize': 1, # line buffered
603
bd30deecdf4a STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 602
diff changeset
21 }
bd30deecdf4a STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 602
diff changeset
22
606
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
23 def __init__(self, command, **kwargs):
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
24
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
25 # setup arguments
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
26 self.command = command
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
27 _kwargs = self.defaults.copy()
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
28 _kwargs.update(kwargs)
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
29
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
30 # output buffer
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
31 self.output_buffer = tempfile.SpooledTemporaryFile()
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
32 self.location = 0
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
33 self.output = []
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
34 _kwargs['stdout'] = self.output_buffer
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
35
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
36 # launch subprocess
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
37 self.start = time.time()
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
38 subprocess.Popen.__init__(self, *args, **_kwargs)
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
39
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
40 def wait(self, maxtime=None, sleep=1.):
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
41 """
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
42 maxtime -- timeout in seconds
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
43 sleep -- number of seconds to sleep between polling
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
44 """
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
45 while self.poll() is None:
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
46
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
47 # check for timeout
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
48 curr_time = time.time()
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
49 run_time = curr_time - self.start
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
50 if run_time > maxtime:
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
51 # TODO: read from output
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
52 return process.kill()
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
53
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
54 # naptime
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
55 if sleep:
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
56 time.sleep(sleep)
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
57
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
58 # read from output buffer
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
59 self.output_buffer.seek(self.location)
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
60 read = self.output_buffer.read()
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
61 self.location += len(read)
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
62
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
63 def commandline(self):
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
64 """returns string of command line"""
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
65
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
66 if isinstance(self.command, string):
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
67 return self.command
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
68 return subprocess.list2cmdline(self.command)
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
69
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
70 __str__ = commandline
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
71
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
72
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
73 def main(args=sys.argv[1:]):
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
74 """CLI"""
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
75
600
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
76 # available programs
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
77 progs = {'yes': ["yes"],
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
78 'ping': ['ping', 'google.com']}
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
79
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
80
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
81 # parse command line
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
82 usage = '%prog [options]'
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
83 parser = argparse.ArgumentParser(usage=usage, description=__doc__)
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
84 parser.add_argument("-t", "--time", dest="time",
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
85 type=float, default=4.,
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
86 help="seconds to run for")
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
87 parser.add_argument("-s", "--sleep", dest="sleep",
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
88 type=float, default=1.,
600
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
89 help="sleep this number of seconds between polling")
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
90 parser.add_argument("-p", "--prog", dest='program',
606
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
91 choices=progs.keys(), default='ping',
600
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
92 help="subprocess to run")
606
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
93 parser.add_argument("--list-programs", dest='list_programs',
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
94 action='store_true', default=False,
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
95 help="list available programs")
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
96 options = parser.parse_args(args)
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
97
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
98
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
99 # select program
600
a77f7022cc06 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 599
diff changeset
100 prog = progs[options.program]
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
101
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
102 # start the main subprocess loop
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
103 # TODO -> OO
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
104 output = tempfile.SpooledTemporaryFile()
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
105 start = time.time()
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
106 proc = subprocess.Popen(prog, stdout=output)
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
107 location = 0
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
108 while proc.poll() is None:
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
109 curr_time = time.time()
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
110 run_time = curr_time - start
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
111 if run_time > options.time:
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
112 proc.kill()
599
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
113 output.seek(location)
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
114 read = output.read()
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
115 location += len(read)
782dc37492c4 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 596
diff changeset
116 print ('[{}] {}\n{}'.format(run_time, read, '-==-'*10))
606
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
117 if options.sleep:
5b561c7b2005 STUB: python/multiproc.py
Jeff Hammel <k0scist@gmail.com>
parents: 603
diff changeset
118 time.sleep(options.sleep)
596
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
119
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
120 # reset tempfile
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
121 output.seek(0)
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
122
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
123 n_lines = len(output.read().splitlines())
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
124 print ("{}: {} lines".format(subprocess.list2cmdline(prog), n_lines))
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
125
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
126 if __name__ == '__main__':
Jeff Hammel <k0scist@gmail.com>
parents:
diff changeset
127 main()