]> git.ipfire.org Git - pbs.git/commitdiff
builders: Refactor auto-scaling
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 24 Jan 2025 15:56:35 +0000 (15:56 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 24 Jan 2025 15:56:35 +0000 (15:56 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/builders.py
src/buildservice/jobs.py
src/scripts/pakfire-build-service

index c4fdef1479c20041536d0bdec9dffbc020b022a1..040b096998381bf49c94b4e114c6b383ab1f11e2 100644 (file)
@@ -276,15 +276,19 @@ class Builders(base.Object):
                # XXX max queue length
                threshold = datetime.timedelta(minutes=5)
 
-               # Fetch all builders
-               builders = [b async for b in self]
-
-               # Fetch the priority for each builder
-               builders = dict(
-                       zip(builders, await asyncio.gather(
-                               *(b._autoscale_sort() for b in builders),
-                       )),
-               )
+               builders = {}
+
+               # Fetch all builders and their value for sorting
+               async with asyncio.TaskGroup() as tg:
+                       async for builder in self:
+                               task = tg.create_task(
+                                       builder._autoscale_sort(),
+                               )
+
+                               builders[builder] = task
+
+               # Fetch the results
+               builders = { builder : builders[builder].result() for builder in builders }
 
                # Sort all builders after their priority
                builders = sorted(builders, key=lambda b: (-builders[b], b))
@@ -297,7 +301,7 @@ class Builders(base.Object):
                # Run through all build jobs and allocate them to a builder.
                # If a builder is full (i.e. reaches the threshold of its build time),
                # we move on to the next builder until that is full and so on.
-               for job in self.backend.jobs.queue:
+               async for job in self.backend.jobs.queue:
                        log.debug("Processing job %s..." % job)
 
                        for builder in builders:
@@ -327,7 +331,7 @@ class Builders(base.Object):
 
                # Find all builders that are no longer needed and can be shut down
                builders_to_be_shut_down = [
-                       builder for builder in builders if not queue[builder] and builder.is_idle()
+                       builder for builder in builders if not queue[builder] and await builder.is_idle()
                ]
 
                async with asyncio.TaskGroup() as tasks:
index 4b01cece0b9453105223917f040be7af04bbb8df..dcfc357cc55248f294ab0fd0af0151a760dd5a68 100644 (file)
@@ -351,7 +351,7 @@ class Queue(base.Object):
                                        continue
 
                                # Skip any builders that are already full
-                               elif builder.is_full():
+                               elif await builder.is_full():
                                        continue
 
                                # Add it to the queue
@@ -391,7 +391,7 @@ class Queue(base.Object):
                                # 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 not builder.is_full():
+                               if not await builder.is_full():
                                        builders.put(builder)
 
                        # Auto-scale builders
index 2c5e1cbe607a9478f3c3e1ca153a4a742d97b0ae..a919a7fc205ea05fd66ca41b7b20d77e4993cbb3 100644 (file)
@@ -22,6 +22,9 @@ class Cli(object):
                        "builds:create-test-builds" : self._builds_create_test_builds,
                        "builds:reverse-requires"   : self._builds_reverse_requires,
 
+                       # Builders
+                       "builders:autoscale"  : self.backend.builders.autoscale,
+
                        # Certificates
                        "load-certificate"    : self.backend.load_certificate,