Merge "Quantize relative priority"

This commit is contained in:
Zuul 2021-12-15 22:19:26 +00:00 committed by Gerrit Code Review
commit 230681eb98
3 changed files with 60 additions and 1 deletions

View File

@ -373,6 +373,12 @@ The following sections of ``zuul.conf`` are used by the scheduler:
faster for projects with fewer changes in a system dominated by
projects with more changes.
After the first 10 changes, the relative priority becomes more
coarse (batching groups of 10 changes at the same priority).
Likewise, after 100 changes they are batchen in groups of 100.
This is to avoid causing additional load with unecessary
priority changes if queues are long.
If this value is ``False`` (the default), then node requests are
sorted by pipeline precedence followed by the order in which
they were submitted. If this is ``True``, they are sorted by

View File

@ -6398,6 +6398,48 @@ For CI problems and help debugging, contact ci@example.org"""
self.fake_nodepool.unpause()
self.waitUntilSettled()
@simple_layout('layouts/two-projects-integrated.yaml')
def test_nodepool_relative_priority_long(self):
"Test that nodes are requested at the relative priority"
self.fake_nodepool.pause()
count = 13
changes = []
for x in range(count):
change = self.fake_gerrit.addFakeChange(
'org/project', 'master', 'A')
self.fake_gerrit.addEvent(change.getPatchsetCreatedEvent(1))
self.waitUntilSettled()
changes.append(change)
reqs = self.fake_nodepool.getNodeRequests()
self.assertEqual(len(reqs), 13)
# The requests come back sorted by priority.
for x in range(10):
self.assertEqual(reqs[x]['relative_priority'], x)
self.assertEqual(reqs[10]['relative_priority'], 10)
self.assertEqual(reqs[11]['relative_priority'], 10)
self.assertEqual(reqs[12]['relative_priority'], 10)
# Fulfill only the first request
self.fake_nodepool.fulfillRequest(reqs[0])
for x in iterate_timeout(30, 'fulfill request'):
reqs = list(self.scheds.first.sched.nodepool.getNodeRequests())
if len(reqs) < count:
break
self.waitUntilSettled()
reqs = self.fake_nodepool.getNodeRequests()
self.assertEqual(len(reqs), 12)
for x in range(10):
self.assertEqual(reqs[x]['relative_priority'], x)
self.assertEqual(reqs[10]['relative_priority'], 10)
self.assertEqual(reqs[11]['relative_priority'], 10)
self.fake_nodepool.unpause()
self.waitUntilSettled()
@simple_layout('layouts/two-projects-integrated.yaml')
def test_nodepool_relative_priority_gate(self):
"Test that nodes are requested at the relative priority"

View File

@ -182,7 +182,18 @@ class PipelineManager(metaclass=ABCMeta):
items = [i for i in items
if i.change.project in queue and
i.live]
return items.index(item)
index = items.index(item)
# Quantize on a logarithmic scale so that we don't constantly
# needlessly adjust thousands of node requests.
# If we're in the top 10 changes, return the accurate number.
if index < 10:
return index
# After 10, batch then in groups of 10 (so items 10-19 are all
# at node priority 10, 20-29 at 20, etc).
if index < 100:
return index // 10 * 10
# After 100, batch in groups of 100.
return index // 100 * 100
def resolveChangeReferences(self, change_references):
return self.resolveChangeKeys(