"with maxConcurrent 1 a second branch stays PENDING until the first
finished" failed on CI on a branch that does not touch BuildExecutor, and
the message named the cause: expected: but was:. Not
merely started -- already finished.
The test started two builds of two branches back to back and assumed the
first one started would get the single slot. Nothing provides that. Each
branch has a worker thread of its own, both call slot.acquire() inside
execute, and RUNNING is recorded only afterwards; which thread arrives
first is the scheduler's business. Semaphore fairness orders threads
already waiting, not two threads racing to arrive. So branch-b took the
slot, ran echo ok to the end, released it, branch-a went RUNNING -- the
state the test was waiting for -- and the next line found branch-b
finished. Starting the two in the other order reproduces it every time.
The gate file from 9221550 could never cover this: it holds branch-a only
once branch-a already has the slot.
branch-b is now enqueued after branch-a is observed RUNNING, which is
proof the slot is taken, and the gate keeps it taken. No window is left,
and nothing is assumed about scheduling. It is also the case the test is
named after and the one that happens in production: a push arriving while
another branch builds. The transitions assertion at the end, which is the
real requirement, is unchanged.
"with maxConcurrent 1 a second branch stays PENDING until the first
finished" failed on CI on a branch that does not touch BuildExecutor, and
the message named the cause: expected:<PENDING> but was:<SUCCESS>. Not
merely started -- already finished.
The test started two builds of two branches back to back and assumed the
first one started would get the single slot. Nothing provides that. Each
branch has a worker thread of its own, both call slot.acquire() inside
execute, and RUNNING is recorded only afterwards; which thread arrives
first is the scheduler's business. Semaphore fairness orders threads
already waiting, not two threads racing to arrive. So branch-b took the
slot, ran `echo ok` to the end, released it, branch-a went RUNNING -- the
state the test was waiting for -- and the next line found branch-b
finished. Starting the two in the other order reproduces it every time.
The gate file from 9221550 could never cover this: it holds branch-a only
once branch-a already has the slot.
branch-b is now enqueued after branch-a is observed RUNNING, which is
proof the slot is taken, and the gate keeps it taken. No window is left,
and nothing is assumed about scheduling. It is also the case the test is
named after and the one that happens in production: a push arriving while
another branch builds. The transitions assertion at the end, which is the
real requirement, is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"with maxConcurrent 1 a second branch stays PENDING until the first
finished" failed on CI on a branch that does not touch BuildExecutor, and
the message named the cause: expected:<PENDING> but was:<SUCCESS>. Not
merely started -- already finished.
The test started two builds of two branches back to back and assumed the
first one started would get the single slot. Nothing provides that. Each
branch has a worker thread of its own, both call slot.acquire() inside
execute, and RUNNING is recorded only afterwards; which thread arrives
first is the scheduler's business. Semaphore fairness orders threads
already waiting, not two threads racing to arrive. So branch-b took the
slot, ran `echo ok` to the end, released it, branch-a went RUNNING -- the
state the test was waiting for -- and the next line found branch-b
finished. Starting the two in the other order reproduces it every time.
The gate file from 9221550 could never cover this: it holds branch-a only
once branch-a already has the slot.
branch-b is now enqueued after branch-a is observed RUNNING, which is
proof the slot is taken, and the gate keeps it taken. No window is left,
and nothing is assumed about scheduling. It is also the case the test is
named after and the one that happens in production: a push arriving while
another branch builds. The transitions assertion at the end, which is the
real requirement, is unchanged.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
"with maxConcurrent 1 a second branch stays PENDING until the first
finished" failed on CI on a branch that does not touch BuildExecutor, and
the message named the cause: expected: but was:. Not
merely started -- already finished.
The test started two builds of two branches back to back and assumed the
first one started would get the single slot. Nothing provides that. Each
branch has a worker thread of its own, both call slot.acquire() inside
execute, and RUNNING is recorded only afterwards; which thread arrives
first is the scheduler's business. Semaphore fairness orders threads
already waiting, not two threads racing to arrive. So branch-b took the
slot, ran
echo okto the end, released it, branch-a went RUNNING -- thestate the test was waiting for -- and the next line found branch-b
finished. Starting the two in the other order reproduces it every time.
The gate file from
9221550could never cover this: it holds branch-a onlyonce branch-a already has the slot.
branch-b is now enqueued after branch-a is observed RUNNING, which is
proof the slot is taken, and the gate keeps it taken. No window is left,
and nothing is assumed about scheduling. It is also the case the test is
named after and the one that happens in production: a push arriving while
another branch builds. The transitions assertion at the end, which is the
real requirement, is unchanged.
Co-Authored-By: Claude Opus 5 noreply@anthropic.com
d4d83b7d2ato098e564979