Support relative priority of node requests
The launcher now processes node requests in relative priority order. This relies on the new node request cache because the relative priority field may be updated at any time by the requestor. Needed-By: https://review.openstack.org/615356 Change-Id: If893c34c6652b9649bfb6f1d9f7b942c549c98b4
This commit is contained in:
parent
40162102a7
commit
854f638e35
|
@ -164,7 +164,15 @@ class PoolWorker(threading.Thread):
|
|||
if provider.max_concurrency == 0:
|
||||
return
|
||||
|
||||
for req_id in self.zk.getNodeRequests():
|
||||
# Sort requests by queue priority, then, for all requests at
|
||||
# the same priority, use the relative_priority field to
|
||||
# further sort, then finally, the submission order.
|
||||
requests = list(self.zk.nodeRequestIterator())
|
||||
requests.sort(key=lambda r: (r.id.split('-')[0],
|
||||
r.relative_priority,
|
||||
r.id.split('-')[1]))
|
||||
|
||||
for req in requests:
|
||||
if self.paused_handler:
|
||||
return
|
||||
|
||||
|
@ -182,7 +190,7 @@ class PoolWorker(threading.Thread):
|
|||
active_threads, provider.max_concurrency)
|
||||
return
|
||||
|
||||
req = self.zk.getNodeRequest(req_id)
|
||||
req = self.zk.getNodeRequest(req.id)
|
||||
if not req:
|
||||
continue
|
||||
|
||||
|
|
|
@ -1792,3 +1792,33 @@ class TestLauncher(tests.DBTestCase):
|
|||
|
||||
req3 = self.waitForNodeRequest(req3)
|
||||
self.assertEqual(req3.state, zk.FAILED)
|
||||
|
||||
def test_request_order(self):
|
||||
"""Test that requests are handled in sorted order"""
|
||||
configfile = self.setup_config('node_no_min_ready.yaml')
|
||||
self.useBuilder(configfile)
|
||||
image = self.waitForImage('fake-provider', 'fake-image')
|
||||
self.assertEqual(image.username, 'zuul')
|
||||
|
||||
req1 = zk.NodeRequest()
|
||||
req1.state = zk.REQUESTED
|
||||
req1.node_types.append('fake-label')
|
||||
req1.relative_priority = 2
|
||||
self.zk.storeNodeRequest(req1)
|
||||
|
||||
req2 = zk.NodeRequest()
|
||||
req2.state = zk.REQUESTED
|
||||
req2.node_types.append('fake-label')
|
||||
req2.relative_priority = 1
|
||||
self.zk.storeNodeRequest(req2)
|
||||
|
||||
pool = self.useNodepool(configfile, watermark_sleep=1)
|
||||
pool.start()
|
||||
|
||||
req2 = self.waitForNodeRequest(req2)
|
||||
self.assertEqual(req2.state, zk.FULFILLED)
|
||||
req1 = self.waitForNodeRequest(req1)
|
||||
self.assertEqual(req1.state, zk.FULFILLED)
|
||||
|
||||
self.assertTrue(req2.id > req1.id)
|
||||
self.assertTrue(req2.state_time < req1.state_time)
|
||||
|
|
|
@ -433,6 +433,7 @@ class NodeRequest(BaseModel):
|
|||
self.nodes = []
|
||||
self.reuse = True
|
||||
self.requestor = None
|
||||
self.relative_priority = 0
|
||||
|
||||
def __repr__(self):
|
||||
d = self.toDict()
|
||||
|
@ -447,7 +448,8 @@ class NodeRequest(BaseModel):
|
|||
self.node_types == other.node_types and
|
||||
self.nodes == other.nodes and
|
||||
self.reuse == other.reuse and
|
||||
self.requestor == other.requestor)
|
||||
self.requestor == other.requestor and
|
||||
self.relative_priority == other.relative_priority)
|
||||
else:
|
||||
return False
|
||||
|
||||
|
@ -461,6 +463,7 @@ class NodeRequest(BaseModel):
|
|||
d['nodes'] = self.nodes
|
||||
d['reuse'] = self.reuse
|
||||
d['requestor'] = self.requestor
|
||||
d['relative_priority'] = self.relative_priority
|
||||
return d
|
||||
|
||||
@staticmethod
|
||||
|
@ -485,6 +488,7 @@ class NodeRequest(BaseModel):
|
|||
self.nodes = d.get('nodes', [])
|
||||
self.reuse = d.get('reuse', True)
|
||||
self.requestor = d.get('requestor')
|
||||
self.relative_priority = d.get('relative_priority', 0)
|
||||
|
||||
|
||||
class Node(BaseModel):
|
||||
|
|
Loading…
Reference in New Issue