Count Pending Runs That Hold macOS Runners

Co-authored-by: raistlin7447 <kris.austin@gmail.com>
This commit is contained in:
Hanif Koh
2026-10-11 05:49:13 +08:00
co-authored by raistlin7447
parent 9f25c89994
commit d4986e44bd
2 changed files with 20 additions and 4 deletions
+8 -4
View File
@@ -71,6 +71,10 @@ def admitted(jobs):
def run_demand(run, jobs):
"""macOS runners a run holds or still needs."""
# A run with no jobs that is pending waits behind another run of its
# concurrency group, which holds the runners for both.
if not jobs and run["status"] in ("pending", "waiting"):
return 0
active = sum(1 for job in jobs if is_macos(job) and job["status"] in ACTIVE)
if macos_done(jobs):
return active
@@ -127,10 +131,10 @@ def measure(api, repo, workflow, run_id, now):
"""Total macOS runners held or needed, one line per run that holds any, and
whether run_id was already let in."""
total, lines, here = 0, [], False
# A run is listed as queued whenever one of its jobs waits for a runner, so a
# queued run can hold runners too. A run can move between the two lists
# between the calls.
runs = {run["id"]: run for status in ("in_progress", "queued")
# A run is listed as queued whenever one of its jobs waits for a runner, and
# as pending whenever one waits in a concurrency group, so runs in any of these
# can hold runners. A run can move between the lists between the calls.
runs = {run["id"]: run for status in ("in_progress", "queued", "pending", "waiting")
for run in list_runs(api, repo, workflow, status=status)}
for run in runs.values():
jobs = api.get(f"repos/{repo}/actions/runs/{run['id']}/jobs",
+12
View File
@@ -139,6 +139,18 @@ class MeasureTest(unittest.TestCase):
self.assertEqual(len(lines), 3)
self.assertFalse(here)
def test_counts_a_pending_run_that_holds_runners(self):
# One of its jobs waits in a concurrency group while its macOS builds run.
pending_pr = dict(PR, status="pending")
api = FakeApi({("runs", "pending"): [pending_pr], jobs_path(2): [gate("arm64"), build("arm64")]})
total, _, _ = admission.measure(api, "o/r", "build_all.yml", 99, NOON)
self.assertEqual(total, admission.RESERVE)
def test_a_push_waiting_behind_another_holds_nothing(self):
api = FakeApi({("runs", "pending"): [dict(PUSH, status="pending")], jobs_path(1): []})
total, _, _ = admission.measure(api, "o/r", "build_all.yml", 99, NOON)
self.assertEqual(total, 0)
def test_reads_every_page_of_runs(self):
runs = [dict(PR, id=i) for i in range(150)]
responses = {("runs", "in_progress"): runs}