build queue rate limiting: address PR comments

This commit is contained in:
Jimmy Zelinskie 2016-12-06 20:40:54 -05:00
parent eb69abff8b
commit c41de8ded6
4 changed files with 12 additions and 7 deletions

View file

@ -79,7 +79,7 @@ class WorkQueue(object):
def num_available_jobs_between(self, available_min_time, available_max_time, prefix): def num_available_jobs_between(self, available_min_time, available_max_time, prefix):
""" """
Returns the number of available queue items with a given prefix between the two provided times. Returns the number of available queue items with a given prefix, between the two provided times.
""" """
prefix = prefix.lstrip('/') prefix = prefix.lstrip('/')
available = self._available_jobs(available_max_time, available = self._available_jobs(available_max_time,

View file

@ -291,6 +291,7 @@ class RepositoryBuildList(RepositoryParamResource):
build_request = start_build(repo, prepared, pull_robot_name=pull_robot_name) build_request = start_build(repo, prepared, pull_robot_name=pull_robot_name)
except MaximumBuildsQueuedException: except MaximumBuildsQueuedException:
abort(429, message='Maximum queued build rate exceeded.') abort(429, message='Maximum queued build rate exceeded.')
resp = build_status_view(build_request) resp = build_status_view(build_request)
repo_string = '%s/%s' % (namespace, repository) repo_string = '%s/%s' % (namespace, repository)
headers = { headers = {

View file

@ -16,23 +16,27 @@ from util.morecollections import AttrDict
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
MAX_BUILD_QUEUE_ITEMS = app.config.get('MAX_BUILD_QUEUE_ITEMS', -1) MAX_BUILD_QUEUE_RATE_ITEMS = app.config.get('MAX_BUILD_QUEUE_RATE_ITEMS', -1)
MAX_BUILD_QUEUE_SECS = app.config.get('MAX_BUILD_QUEUE_SECS', -1) MAX_BUILD_QUEUE_RATE_SECS = app.config.get('MAX_BUILD_QUEUE_RATE_SECS', -1)
class MaximumBuildsQueuedException(Exception): class MaximumBuildsQueuedException(Exception):
"""
This exception is raised when a build is requested, but the incoming build
would exceed the configured maximum build rate.
"""
pass pass
def start_build(repository, prepared_build, pull_robot_name=None): def start_build(repository, prepared_build, pull_robot_name=None):
queue_item_prefix = '%s/%s' % (repository.namespace_user.username, repository.name) queue_item_prefix = '%s/%s' % (repository.namespace_user.username, repository.name)
if MAX_BUILD_QUEUE_ITEMS > 0 and MAX_BUILD_QUEUE_SECS > 0: if MAX_BUILD_QUEUE_RATE_ITEMS > 0 and MAX_BUILD_QUEUE_RATE_SECS > 0:
now = datetime.utcnow() now = datetime.utcnow()
available_min = now - timedelta(seconds=MAX_BUILD_QUEUE_SECS) available_min = now - timedelta(seconds=MAX_BUILD_QUEUE_RATE_SECS)
available_builds = dockerfile_build_queue.num_available_jobs_between(available_min, available_builds = dockerfile_build_queue.num_available_jobs_between(available_min,
now, now,
queue_item_prefix) queue_item_prefix)
if available_builds > MAX_BUILD_QUEUE_ITEMS: if available_builds >= MAX_BUILD_QUEUE_RATE_ITEMS:
raise MaximumBuildsQueuedException() raise MaximumBuildsQueuedException()
host = app.config['SERVER_HOSTNAME'] host = app.config['SERVER_HOSTNAME']

View file

@ -107,7 +107,7 @@ def build_trigger_webhook(trigger_uuid, **kwargs):
try: try:
start_build(repo, prepared, pull_robot_name=pull_robot_name) start_build(repo, prepared, pull_robot_name=pull_robot_name)
except MaximumBuildsQueuedException: except MaximumBuildsQueuedException:
abort(429) abort(429, message='Maximum queued build rate exceeded.')
return make_response('Okay') return make_response('Okay')