| Index: appengine/swarming/server/task_request.py
|
| diff --git a/appengine/swarming/server/task_request.py b/appengine/swarming/server/task_request.py
|
| index f9c0674fb834b31bc67f3ccb26799b8f5da96958..b8e6bc04a4f34c2e8f35525542de88b521380f78 100644
|
| --- a/appengine/swarming/server/task_request.py
|
| +++ b/appengine/swarming/server/task_request.py
|
| @@ -542,10 +542,11 @@ class TaskProperties(ndb.Model):
|
|
|
| @property
|
| def dimensions(self):
|
| - """Returns a dict(key, value)."""
|
| + """Returns a list of tuple(key, value)."""
|
| if self.dimensions_dict:
|
| - return self.dimensions_dict
|
| - return dict(i.split(u':', 1) for i in self.dimensions_flat)
|
| + return sorted(self.dimensions_dict.items())
|
| + # Data is already sorted.
|
| + return [tuple(i.split(u':', 1)) for i in self.dimensions_flat]
|
|
|
| @property
|
| def is_terminate(self):
|
| @@ -553,7 +554,7 @@ class TaskProperties(ndb.Model):
|
| return (
|
| not self.caches and
|
| not self.command and
|
| - self.dimensions.keys() == [u'id'] and
|
| + [i[0] for i in self.dimensions] == [u'id'] and
|
| not (self.inputs_ref and self.inputs_ref.isolated) and
|
| not self.cipd_input and
|
| not self.env and
|
| @@ -579,9 +580,12 @@ class TaskProperties(ndb.Model):
|
| return
|
|
|
| # Dimensions.
|
| - if not self.dimensions:
|
| + if self.dimensions_dict:
|
| + raise datastore_errors.BadValueError(
|
| + u'internal error: dimensions_dict cannot be stored anymore')
|
| + if not self.dimensions_flat:
|
| raise datastore_errors.BadValueError(u'dimensions are required')
|
| - keys = self.dimensions.keys()
|
| + keys = [i.split(u':', 1)[0] for i in self.dimensions_flat]
|
| count_pool = sum(1 for k in keys if k == u'pool')
|
| count_id = sum(1 for k in keys if k == u'id')
|
| if not count_pool and not count_id:
|
| @@ -590,7 +594,7 @@ class TaskProperties(ndb.Model):
|
| if count_id > 1:
|
| raise datastore_errors.BadValueError(
|
| u'\'id\' cannot be specified more than once in dimensions')
|
| - if len(keys) > 64:
|
| + if len(self.dimensions_flat) > 64:
|
| raise datastore_errors.BadValueError(
|
| 'dimensions can have up to 64 entries')
|
| if not _is_sorted(self.dimensions_flat):
|
| @@ -827,7 +831,7 @@ def create_termination_task(bot_id, allow_high_priority):
|
| TaskRequest for priority 0 (highest) termination task.
|
| """
|
| properties = TaskProperties(
|
| - dimensions_dict={u'id': unicode(bot_id)},
|
| + dimensions_flat=[u'id:%s' % unicode(bot_id)],
|
| execution_timeout_secs=0,
|
| grace_period_secs=0,
|
| io_timeout_secs=0)
|
| @@ -994,7 +998,7 @@ def init_new_request(request, allow_high_priority, secret_bytes_ent):
|
| request.tags.append('priority:%s' % request.priority)
|
| request.tags.append('user:%s' % request.user)
|
| request.tags.append('service_account:%s' % request.service_account)
|
| - for key, value in request.properties.dimensions.iteritems():
|
| + for key, value in request.properties.dimensions:
|
| request.tags.append('%s:%s' % (key, value))
|
| request.tags = sorted(set(request.tags))
|
|
|
| @@ -1036,8 +1040,10 @@ def new_request_clone(original_request, original_secret_bytes,
|
| if original_request.properties.is_terminate:
|
| raise ValueError('cannot clone a terminate request')
|
| orig_props = original_request.properties.to_dict()
|
| - dimensions_dict = orig_props.pop(u'dimensions')
|
| - properties = TaskProperties(dimensions_dict=dimensions_dict, **orig_props)
|
| + dimensions_flat = [
|
| + u'%s:%s' % (k, v) for k, v in orig_props.pop(u'dimensions')
|
| + ]
|
| + properties = TaskProperties(dimensions_flat=dimensions_flat, **orig_props)
|
| properties.idempotent = False
|
| expiration_ts = (
|
| now + (original_request.expiration_ts - original_request.created_ts))
|
|
|