Don't buffer stdout/stderr in command_wrapper.py
Otherwise, commands that take a long time to complete, but produce some status
output, such as gsutil cp, will cause the buildbot's timeout to trigger.
BUG=none
TEST=manually, works on linux :)
Review URL: http://codereview.chromium.org/10085001
git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/command_wrapper/bin@134087 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/command_wrapper.py b/command_wrapper.py
index 249db31..91f9b6e 100755
--- a/command_wrapper.py
+++ b/command_wrapper.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
#
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -25,6 +25,7 @@
LOG_TIMEOUT = 10
+ON_POSIX = 'posix' in sys.builtin_module_names
def LogCommand(options, command_id,
@@ -81,6 +82,15 @@
return wrapper['result']
+def Tee(fd, string_buffer, forward_fd):
+ """Read characters from fd and both append them to a buffer and write them to
+ forward_fd."""
+ for char in iter(lambda: fd.read(1), ''):
+ string_buffer += char
+ forward_fd.write(char)
+ fd.close()
+
+
def main(argv):
parser = optparse.OptionParser()
parser.add_option('-r', '--retries', dest='retries',
@@ -113,10 +123,24 @@
tm = time.time()
p = subprocess.Popen(cmd, shell=True,
stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- (p_stdout, p_stderr) = p.communicate()
- sys.stdout.write(p_stdout)
- sys.stderr.write(p_stderr)
+ stderr=subprocess.PIPE,
+ close_fds=ON_POSIX)
+ p_stdout = ''
+ t_stdout = threading.Thread(target=Tee,
+ args=(p.stdout, p_stdout, sys.stdout))
+ t_stdout.start()
+
+ p_stderr = ''
+ t_stderr = threading.Thread(target=Tee,
+ args=(p.stderr, p_stderr, sys.stderr))
+ t_stderr.start()
+
+ p.wait()
+
+ t_stdout.join()
+ t_stderr.join()
+
+
runtime = time.time() - tm
accept = RunWithTimeout(LOG_TIMEOUT, LogCommand,
options, command_id, r, cmd,