From 9a161f9146a5e7e4da398431a8aa52f1f8a44dd7 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sun, 30 Mar 2025 22:11:53 -0400 Subject: [PATCH 1/2] fix min_avail calculation --- kojihub/scheduler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kojihub/scheduler.py b/kojihub/scheduler.py index c649827e..9f0757cd 100644 --- a/kojihub/scheduler.py +++ b/kojihub/scheduler.py @@ -377,7 +377,7 @@ class TaskScheduler(object): refusals = self.get_refusals() for task in self.free_tasks: task['_hosts'] = [] - min_avail = min(0, task['weight'] - self.capacity_overcommit) + min_avail = max(0, task['weight'] - self.capacity_overcommit) h_refused = refusals.get(task['task_id'], {}) for host in self.hosts_by_bin.get(task['_bin'], []): if (host['ready'] and @@ -402,7 +402,7 @@ class TaskScheduler(object): # tasks are already in priority order for task in self.free_tasks: - min_avail = task['weight'] - self.capacity_overcommit + min_avail = max(0, task['weight'] - self.capacity_overcommit) task['_hosts'].sort(key=lambda h: h['_rank']) logger.debug('Task %i choices: %s', task['task_id'], [(h['name'], "%(_rank).2f" % h) for h in task['_hosts']]) From b3ba2fac9135f06f12d94927ad01576b260dc720 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Sun, 30 Mar 2025 22:23:46 -0400 Subject: [PATCH 2/2] unit test --- tests/test_hub/test_scheduler.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/test_hub/test_scheduler.py b/tests/test_hub/test_scheduler.py index a819d521..656076f0 100644 --- a/tests/test_hub/test_scheduler.py +++ b/tests/test_hub/test_scheduler.py @@ -222,6 +222,23 @@ class TestDoSchedule(BaseTest): self.assertEqual(t_assigned, list(range(5))) self.assertEqual(h_used, list(range(5))) + def test_stop_at_capacity(self): + # just one host + host = self.mkhost(id=1, capacity=5.0) + self.sched._get_hosts.return_value = [host] + self.sched.get_hosts() + # and more tasks than will fit + self.sched.free_tasks = [self.mktask(task_id=n, weight=1.0) for n in range(10)] + + self.sched.do_schedule() + + # 5 tasks with weight=1.0 should fill up capacity + # (overcommit only applies for a single task going over) + self.assertEqual(len(self.assigns), 5) + t_assigned = [t['task_id'] for t, h in self.assigns] + t_assigned.sort() + self.assertEqual(t_assigned, list(range(5))) + def test_active_tasks(self): self.context.opts['CapacityOvercommit'] = 1.0 hosts = [self.mkhost(id=n, capacity=2.0) for n in range(5)]