From: Michael Tremer Date: Thu, 27 Apr 2023 15:32:54 +0000 (+0000) Subject: jobs: Refactor the dispatch algorithm to dispatch mutliple jobs at once X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cadd9144499fd18f7f5812f3f7842483bf464700;p=pbs.git jobs: Refactor the dispatch algorithm to dispatch mutliple jobs at once Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/jobs.py b/src/buildservice/jobs.py index 2c95eff6..fbc27375 100644 --- a/src/buildservice/jobs.py +++ b/src/buildservice/jobs.py @@ -6,6 +6,7 @@ import gzip import hashlib import logging import os +import queue import shutil import pakfire @@ -152,29 +153,46 @@ class Queue(base.Object): """ log.debug("Dispatching jobs...") - # Process all builders and assign jobs - # We prioritize builders with fewer jobs + # Create a queue for all builders + builders = queue.SimpleQueue() + + # Add all builders to the queue in ascending order of running jobs for builder in sorted(self.backend.builders.connections, key=lambda b: len(b.jobs)): + # Skip builders that are not ready + if not builder.is_ready(): + continue + + builders.put(builder) + + # Run for as long as we have unprocessed builders + while not builders.empty(): + # Take the first builder + builder = builders.get() + log.debug(" Processing builder %s" % builder) with self.backend.db.transaction(): - if not builder.is_ready(): - log.debug(" Builder %s is not ready" % builder) - continue - # We are ready for a new job job = self.pop(builder) - if job: - try: - builder.dispatch_job(job) - # Ignore if the builder suddenly went away - except BuilderNotOnlineError: - pass + # If no job could be found for this builder, we simply continue + if not job: + log.debug(" No jobs processable for %s" % builder) + continue + + # If we have a job, we dispatch it to the builder + try: + builder.dispatch_job(job) + # Ignore if the builder suddenly went away + except BuilderNotOnlineError: continue - log.debug(" No jobs processable for %s" % builder) + # If the builder has not any free slots remaining, we put it back in the + # queue to fill it up, but we give priority to builders who have fewer + # jobs to run. + if len(builder.jobs) < builder.max_jobs: + builders.put(builder) # Auto-scale builders await self.backend.builders.autoscale()