From a4d8caf302d189caea20c84b37d556f2f503d646 Mon Sep 17 00:00:00 2001 From: Craig Tracey Date: Fri, 9 Oct 2015 22:55:52 -0400 Subject: [PATCH] Add parallel builds This change runs builds in parallel. By default all projects run simultaneously unless --synchronous is specified. This should speed up build times dramatically. --- giftwrap/build_spec.py | 3 ++- giftwrap/builders/__init__.py | 14 +++++++++++++- giftwrap/settings.py | 4 +++- giftwrap/shell.py | 4 +++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/giftwrap/build_spec.py b/giftwrap/build_spec.py index c0a7e2b..dbcb555 100644 --- a/giftwrap/build_spec.py +++ b/giftwrap/build_spec.py @@ -22,7 +22,7 @@ from giftwrap.settings import Settings class BuildSpec(object): - def __init__(self, manifest, version, build_type=None): + def __init__(self, manifest, version, build_type=None, parallel=True): self._manifest = yaml.load(manifest) self.version = version self.build_type = build_type @@ -31,6 +31,7 @@ class BuildSpec(object): manifest_settings['version'] = version if build_type: manifest_settings['build_type'] = build_type + manifest_settings['parallel_build'] = parallel self.settings = Settings.factory(manifest_settings) self.projects = self._render_projects() diff --git a/giftwrap/builders/__init__.py b/giftwrap/builders/__init__.py index 666507a..fede4c1 100644 --- a/giftwrap/builders/__init__.py +++ b/giftwrap/builders/__init__.py @@ -16,6 +16,7 @@ import logging import os +import threading from giftwrap.gerrit import GerritReview @@ -84,8 +85,19 @@ class Builder(object): self._temp_src_dir = os.path.join(self._temp_dir, 'src') LOG.debug("Temporary working directory: %s", self._temp_dir) + threads = [] for project in spec.projects: - self._build_project(project) + if spec.settings.parallel_build: + t = threading.Thread(target=self._build_project, + args=(project,)) + threads.append(t) + t.start() + else: + self._build_project(project) + + if spec.settings.parallel_build: + for thread in threads: + thread.join() self._finalize_build() diff --git a/giftwrap/settings.py b/giftwrap/settings.py index 6175b2c..d6962e1 100644 --- a/giftwrap/settings.py +++ b/giftwrap/settings.py @@ -30,7 +30,8 @@ class Settings(object): def __init__(self, build_type=DEFAULT_BUILD_TYPE, package_name_format=None, version=None, base_path=None, install_path=None, gerrit_dependencies=True, - force_overwrite=False, output_dir=None, include_config=True): + force_overwrite=False, output_dir=None, include_config=True, + parallel_build=True): if not version: raise Exception("'version' is a required settings") self.build_type = build_type @@ -42,6 +43,7 @@ class Settings(object): self.force_overwrite = force_overwrite self._output_dir = output_dir self.include_config = include_config + self.parallel_build = parallel_build @property def package_name_format(self): diff --git a/giftwrap/shell.py b/giftwrap/shell.py index a461fed..f46ce1c 100644 --- a/giftwrap/shell.py +++ b/giftwrap/shell.py @@ -46,7 +46,7 @@ def build(args): with open(args.manifest, 'r') as fh: manifest = fh.read() - buildspec = BuildSpec(manifest, args.version, args.type) + buildspec = BuildSpec(manifest, args.version, args.type, args.parallel) builder = BuilderFactory.create_builder(args.type, buildspec) def _signal_handler(*args): @@ -80,6 +80,8 @@ def main(): build_subcmd.add_argument('-v', '--version') build_subcmd.add_argument('-t', '--type', choices=('docker', 'package'), required=True) + build_subcmd.add_argument('-s', '--synchronous', dest='parallel', + action='store_false') build_subcmd.set_defaults(func=build) args = parser.parse_args()