summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.openstack.org>2018-11-30 01:58:40 +0000
committerGerrit Code Review <review@openstack.org>2018-11-30 01:58:40 +0000
commit7111fcb407a11baa1ea0d2bbee7ba76ec748e884 (patch)
tree0c0b114af45766b6030401da1a8c695e2127b4b9
parent81936cd818bbf5cf8084160c112e4a1a5a5aa03b (diff)
parent854f638e358e59b64aeeebb346a6551636fd3c1f (diff)
Merge "Support relative priority of node requests"
-rwxr-xr-xnodepool/launcher.py12
-rw-r--r--nodepool/tests/unit/test_launcher.py30
-rwxr-xr-xnodepool/zk.py6
3 files changed, 45 insertions, 3 deletions
diff --git a/nodepool/launcher.py b/nodepool/launcher.py
index cabf5bf..9e0f15f 100755
--- a/nodepool/launcher.py
+++ b/nodepool/launcher.py
@@ -159,7 +159,15 @@ class PoolWorker(threading.Thread, stats.StatsReporter):
159 if provider.max_concurrency == 0: 159 if provider.max_concurrency == 0:
160 return 160 return
161 161
162 for req_id in self.zk.getNodeRequests(): 162 # Sort requests by queue priority, then, for all requests at
163 # the same priority, use the relative_priority field to
164 # further sort, then finally, the submission order.
165 requests = list(self.zk.nodeRequestIterator())
166 requests.sort(key=lambda r: (r.id.split('-')[0],
167 r.relative_priority,
168 r.id.split('-')[1]))
169
170 for req in requests:
163 if self.paused_handler: 171 if self.paused_handler:
164 return 172 return
165 173
@@ -177,7 +185,7 @@ class PoolWorker(threading.Thread, stats.StatsReporter):
177 active_threads, provider.max_concurrency) 185 active_threads, provider.max_concurrency)
178 return 186 return
179 187
180 req = self.zk.getNodeRequest(req_id) 188 req = self.zk.getNodeRequest(req.id)
181 if not req: 189 if not req:
182 continue 190 continue
183 191
diff --git a/nodepool/tests/unit/test_launcher.py b/nodepool/tests/unit/test_launcher.py
index a4ca282..49bb688 100644
--- a/nodepool/tests/unit/test_launcher.py
+++ b/nodepool/tests/unit/test_launcher.py
@@ -1794,3 +1794,33 @@ class TestLauncher(tests.DBTestCase):
1794 1794
1795 req3 = self.waitForNodeRequest(req3) 1795 req3 = self.waitForNodeRequest(req3)
1796 self.assertEqual(req3.state, zk.FAILED) 1796 self.assertEqual(req3.state, zk.FAILED)
1797
1798 def test_request_order(self):
1799 """Test that requests are handled in sorted order"""
1800 configfile = self.setup_config('node_no_min_ready.yaml')
1801 self.useBuilder(configfile)
1802 image = self.waitForImage('fake-provider', 'fake-image')
1803 self.assertEqual(image.username, 'zuul')
1804
1805 req1 = zk.NodeRequest()
1806 req1.state = zk.REQUESTED
1807 req1.node_types.append('fake-label')
1808 req1.relative_priority = 2
1809 self.zk.storeNodeRequest(req1)
1810
1811 req2 = zk.NodeRequest()
1812 req2.state = zk.REQUESTED
1813 req2.node_types.append('fake-label')
1814 req2.relative_priority = 1
1815 self.zk.storeNodeRequest(req2)
1816
1817 pool = self.useNodepool(configfile, watermark_sleep=1)
1818 pool.start()
1819
1820 req2 = self.waitForNodeRequest(req2)
1821 self.assertEqual(req2.state, zk.FULFILLED)
1822 req1 = self.waitForNodeRequest(req1)
1823 self.assertEqual(req1.state, zk.FULFILLED)
1824
1825 self.assertTrue(req2.id > req1.id)
1826 self.assertTrue(req2.state_time < req1.state_time)
diff --git a/nodepool/zk.py b/nodepool/zk.py
index da850ad..5a65b2e 100755
--- a/nodepool/zk.py
+++ b/nodepool/zk.py
@@ -440,6 +440,7 @@ class NodeRequest(BaseModel):
440 self.nodes = [] 440 self.nodes = []
441 self.reuse = True 441 self.reuse = True
442 self.requestor = None 442 self.requestor = None
443 self.relative_priority = 0
443 444
444 def __repr__(self): 445 def __repr__(self):
445 d = self.toDict() 446 d = self.toDict()
@@ -454,7 +455,8 @@ class NodeRequest(BaseModel):
454 self.node_types == other.node_types and 455 self.node_types == other.node_types and
455 self.nodes == other.nodes and 456 self.nodes == other.nodes and
456 self.reuse == other.reuse and 457 self.reuse == other.reuse and
457 self.requestor == other.requestor) 458 self.requestor == other.requestor and
459 self.relative_priority == other.relative_priority)
458 else: 460 else:
459 return False 461 return False
460 462
@@ -468,6 +470,7 @@ class NodeRequest(BaseModel):
468 d['nodes'] = self.nodes 470 d['nodes'] = self.nodes
469 d['reuse'] = self.reuse 471 d['reuse'] = self.reuse
470 d['requestor'] = self.requestor 472 d['requestor'] = self.requestor
473 d['relative_priority'] = self.relative_priority
471 return d 474 return d
472 475
473 @staticmethod 476 @staticmethod
@@ -492,6 +495,7 @@ class NodeRequest(BaseModel):
492 self.nodes = d.get('nodes', []) 495 self.nodes = d.get('nodes', [])
493 self.reuse = d.get('reuse', True) 496 self.reuse = d.get('reuse', True)
494 self.requestor = d.get('requestor') 497 self.requestor = d.get('requestor')
498 self.relative_priority = d.get('relative_priority', 0)
495 499
496 500
497class Node(BaseModel): 501class Node(BaseModel):