Mercurial > bitten > bitten-test
changeset 372:67372eba421c
Change building order; rather than just build in reverse revision order (which tends to get stuck if you have a bunch of revisions on a single branch), build the newest revision on each branch before you go backwards and fill in the previous revisions.
author | wbell |
---|---|
date | Mon, 23 Jul 2007 21:49:41 +0000 |
parents | 71f7d5e13b11 |
children | b81c67778df7 |
files | bitten/queue.py |
diffstat | 1 files changed, 74 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/bitten/queue.py +++ b/bitten/queue.py @@ -119,50 +119,89 @@ Otherwise, this function will return C{(None, None)} """ log.debug('Checking for pending builds...') + if len(available_slaves) == 0: + log.debug('No available slaves.') + return None, None repos = self.env.get_repository() + + # delete any old builds. builds_to_delete = [] try: for build in Build.select(self.env, status=Build.PENDING): - - # Ignore pending builds for deactived build configs - config = BuildConfig.fetch(self.env, name=build.config) - if not config.active: - log.info('Dropping build of configuration "%s" at ' - 'revision [%s] on %s because the configuration is ' - 'deactivated', config.name, build.rev, - build.platform) - builds_to_delete.append(build) - continue - - # Stay within the revision limits of the build config - if (config.min_rev and repos.rev_older_than(build.rev, - config.min_rev)) \ - or (config.max_rev and repos.rev_older_than(config.max_rev, - build.rev)): - # This minimum and/or maximum revision has changed since - # this build was enqueued, so drop it - log.info('Dropping build of configuration "%s" at ' - 'revision [%s] on %s because it is outside of the ' - 'revision range of the configuration', config.name, - build.rev, build.platform) - builds_to_delete.append(build) - continue - - # Find a slave for the build platform that is not already building - # something else - slaves = self.slaves.get(build.platform, []) - for idx, slave in enumerate([name for name in slaves if name - in available_slaves]): - slaves.append(slaves.pop(idx)) # Round robin - return build, slave - - return None, None + if self.should_delete_build(build, repos): + builds_to_delete.append(build) finally: - db = self.env.get_db_cnx() + db = self.env.get_db_cnx() for build in builds_to_delete: build.delete(db=db) + # Rather than just take the first build available to + # this slave by version number, we'd like to ensure that + # all the most recent revisions of each config are built + # before we do any older ones. If all the most recent + # revisions are done/in progress for our set of available + # slaves, we'll just fall back to processing the remaining + # builds in descending revision order. First thing we'll do is + # figure out the newest revision that has a build for each config. + + # now make sure all the newest revisions of each config that can be + # built are in-progress or done. + for config in BuildConfig.select(self.env): + # need to loop to get all target platforms of the + # newest revision + newest_rev = -1 + for build in Build.select(self.env, config.name): + if build.rev < newest_rev: + break + if self.should_delete_build(build, repos): + continue + newest_rev = build.rev + + if build.status == Build.PENDING: + slaves = self.slaves.get(build.platform, []) + for idx, slave in enumerate([name for name in slaves + if name in available_slaves]): + slaves.append(slaves.pop(idx)) # Round robin + return build, slave + + # now just assign anyone who's left + for build in Build.select(self.env, status=Build.PENDING): + if self.should_delete_build(build, repos): + continue + # Find a slave for the build platform that is not already building + # something else + slaves = self.slaves.get(build.platform, []) + for idx, slave in enumerate([name for name in slaves if name + in available_slaves]): + slaves.append(slaves.pop(idx)) # Round robin + return build, slave + + log.debug('No pending builds.') + return None, None + + def should_delete_build(self, build, repos): + # Ignore pending builds for deactived build configs + config = BuildConfig.fetch(self.env, build.config) + if not config.active: + log.info('Dropping build of configuration "%s" at ' + 'revision [%s] on "%s" because the configuration is ' + 'deactivated', config.name, build.rev, TargetPlatform.fetch(self.env, build.platform).name) + return True + # Stay within the revision limits of the build config + if (config.min_rev and repos.rev_older_than(build.rev, + config.min_rev)) \ + or (config.max_rev and repos.rev_older_than(config.max_rev, + build.rev)): + # This minimum and/or maximum revision has changed since + # this build was enqueued, so drop it + log.info('Dropping build of configuration "%s" at ' + 'revision [%s] on "%s" because it is outside of the ' + 'revision range of the configuration', config.name, + build.rev, TargetPlatform.fetch(self.env, build.platform).name) + return True + return False + def populate(self): """Add a build for the next change on each build configuration to the queue.