Commit e0de9cbe authored by maruel@chromium.org's avatar maruel@chromium.org

Remove the class StdoutAnnotated and clones the object instead.

The end goal is to remove options.stdout, to remove a lot of bookkeeping.

TEST=none
BUG=none

Review URL: http://codereview.chromium.org/3418014

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@59792 0039d316-1c4b-4281-b951-d872f2087c98
parent 8aba5f73
......@@ -1170,6 +1170,10 @@ def Main(argv):
"""Doesn't parse the arguments here, just find the right subcommand to
execute."""
try:
# Make stdout auto-flush so buildbot doesn't kill us during lengthy
# operations. Python as a strong tendency to buffer sys.stdout.
sys.stdout = gclient_utils.MakeFileAutoFlush(sys.stdout)
# Do it late so all commands are listed.
CMDhelp.usage = ('\n\nCommands are:\n' + '\n'.join([
' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip())
......@@ -1198,8 +1202,8 @@ def Main(argv):
options.entries_filename = options.config_filename + '_entries'
if options.jobs < 1:
parser.error('--jobs must be 1 or higher')
# Always autoflush so buildbot doesn't kill us during lengthy operations.
options.stdout = gclient_utils.StdoutAutoFlush(sys.stdout)
# TODO(maruel): Temporary, to be removed.
options.stdout = sys.stdout
# These hacks need to die.
if not hasattr(options, 'revisions'):
......
......@@ -295,31 +295,48 @@ def CheckCallAndFilterAndHeader(args, always=False, **kwargs):
return CheckCallAndFilter(args, **kwargs)
class StdoutAutoFlush(object):
"""Automatically flush after N seconds."""
def __init__(self, stdout, delay=10):
self.lock = threading.Lock()
self.stdout = stdout
self.delay = delay
self.last_flushed_at = time.time()
self.stdout.flush()
def write(self, out):
"""Thread-safe."""
self.stdout.write(out)
def SoftClone(obj):
"""Clones an object. copy.copy() doesn't work on 'file' objects."""
class NewObject(object): pass
new_obj = NewObject()
for member in dir(obj):
if member.startswith('_'):
continue
setattr(new_obj, member, getattr(obj, member))
return new_obj
def MakeFileAutoFlush(fileobj, delay=10):
"""Creates a file object clone to automatically flush after N seconds."""
if hasattr(fileobj, 'last_flushed_at'):
# Already patched. Just update delay.
fileobj.delay = delay
return fileobj
new_fileobj = SoftClone(fileobj)
new_fileobj.lock = threading.Lock()
new_fileobj.last_flushed_at = time.time()
new_fileobj.delay = delay
new_fileobj.old_auto_flush_write = fileobj.write
# Silence pylint.
new_fileobj.flush = fileobj.flush
def auto_flush_write(out):
new_fileobj.old_auto_flush_write(out)
should_flush = False
self.lock.acquire()
new_fileobj.lock.acquire()
try:
if (time.time() - self.last_flushed_at) > self.delay:
if (new_fileobj.delay and
(time.time() - new_fileobj.last_flushed_at) > new_fileobj.delay):
should_flush = True
self.last_flushed_at = time.time()
new_fileobj.last_flushed_at = time.time()
finally:
self.lock.release()
new_fileobj.lock.release()
if should_flush:
self.stdout.flush()
new_fileobj.flush()
def flush(self):
self.stdout.flush()
new_fileobj.write = auto_flush_write
return new_fileobj
class StdoutAnnotated(object):
......
......@@ -25,10 +25,10 @@ class GclientUtilsUnittest(GclientUtilBase):
'CheckCall', 'CheckCallError', 'CheckCallAndFilter',
'CheckCallAndFilterAndHeader', 'Error', 'ExecutionQueue', 'FileRead',
'FileWrite', 'FindFileUpwards', 'FindGclientRoot',
'GetGClientRootAndEntries', 'GetNamedNodeText',
'GetGClientRootAndEntries', 'GetNamedNodeText', 'MakeFileAutoFlush',
'GetNodeNamedAttributeText', 'PathDifference', 'ParseXML', 'Popen',
'PrintableObject', 'RemoveDirectory', 'SplitUrlRevision',
'StdoutAnnotated', 'StdoutAutoFlush', 'SyntaxErrorToError', 'WorkItem',
'PrintableObject', 'RemoveDirectory', 'SoftClone', 'SplitUrlRevision',
'StdoutAnnotated', 'SyntaxErrorToError', 'WorkItem',
'copy', 'errno', 'logging', 'os', 'Queue', 're', 'stat', 'subprocess',
'sys','threading', 'time', 'xml',
]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment