* fix(worker): reserve the capacity slot before announcing the accept
Two changes for #1536 (flaky test_worker_at_capacity_rejects_without_penalty):
The client now inserts into _running BEFORE awaiting the accept send.
Today _send enqueues synchronously so the old order could not actually
interleave — but the reserve-then-announce order is the invariant that
stays correct if _send ever gains backpressure (a bounded outbox is the
natural evolution), instead of silently reopening an over-accept window.
If the accept send fails, the reserved task is cancelled: work the
scheduler never saw accepted must not run to double-execution.
The test now pins the real invariant — no over-concurrency — rather than
the scheduler's bookkeeping timing: on a loaded CI runner the first
attempt can die environmentally (a stream hiccup fails _run, whose
finally frees the slot), after which accepting the second task is the
CORRECT behaviour the old flat assertion punished as a failure. The
assertion now applies only while the first attempt is still running, and
names the over-accept explicitly when it fires.
Fixes#1536
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(worker): release the reserved slot on a cancelled accept-send
CodeRabbit on #1537:
- except BaseException, not Exception: a handler cancelled while the
accept send is in flight must release the reserved slot too, or the
unaccepted task keeps running and double-executes after reassignment.
Fail-before/pass-after regression test included.
- the capacity test now polls the second task out of its dispatch states
instead of sleeping 0.5s, and asserts the penalty-free invariant
(excluded_workers empty) unconditionally — capacity rejections never
exclude the worker regardless of the first attempt's health.
- TaskAccepted.envelope finding skipped: the field is read nowhere
server-side (registration is the only envelope consumer) — pre-existing
unused-field design, not introduced here.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>