1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-09-17 10:40:12 +02:00

Fixed Bug where long outputs to stderr during build process caused a hang

This commit is contained in:
Christopher 2013-10-12 18:20:32 +02:00 committed by Daniel Martí
parent d4cc3edff2
commit 4ec9393759

View File

@ -27,12 +27,36 @@ import tarfile
import traceback
import time
import json
import Queue
import threading
from optparse import OptionParser
import common
from common import BuildException
from common import VCSException
class AsynchronousFileReader(threading.Thread):
'''
Helper class to implement asynchronous reading of a file
in a separate thread. Pushes read lines on a queue to
be consumed in another thread.
'''
def __init__(self, fd, queue):
assert isinstance(queue, Queue.Queue)
assert callable(fd.readline)
threading.Thread.__init__(self)
self._fd = fd
self._queue = queue
def run(self):
'''The body of the tread: read lines and put them on the queue.'''
for line in iter(self._fd.readline, ''):
self._queue.put(line)
def eof(self):
'''Check whether there is no more content to expect.'''
return not self.is_alive() and self._queue.empty()
def get_builder_vm_id():
vd = os.path.join('builder', '.vagrant')
@ -448,20 +472,36 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d
p = subprocess.Popen(['bash', '-x', '-c', cmd], cwd=root_dir,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
for line in iter(p.stdout.readline, ''):
if verbose:
# Output directly to console
sys.stdout.write(line)
sys.stdout.flush()
else:
output += line
for line in iter(p.stderr.readline, ''):
if verbose:
# Output directly to console
sys.stdout.write(line)
sys.stdout.flush()
else:
error += line
stdout_queue = Queue.Queue()
stdout_reader = AsynchronousFileReader(p.stdout, stdout_queue)
stdout_reader.start()
stderr_queue = Queue.Queue()
stderr_reader = AsynchronousFileReader(p.stderr, stderr_queue)
stderr_reader.start()
# Check the queues if we received some output (until there is nothing more to get).
while not stdout_reader.eof() or not stderr_reader.eof():
# Show what we received from standard output.
while not stdout_queue.empty():
line = stdout_queue.get()
if verbose:
# Output directly to console
sys.stdout.write(line)
sys.stdout.flush()
else:
error += line
# Show what we received from standard error.
while not stderr_queue.empty():
line = stderr_queue.get()
if verbose:
# Output directly to console
sys.stdout.write(line)
sys.stdout.flush()
else:
error += line
p.communicate()
if p.returncode != 0:
raise BuildException("Error running build command for %s:%s" %