Repository navigation
[GMLP-10778] Keep busy pool workers and in-flight reservations across a broker reconnect (5.6.3+gumloop_0.2.1) - #5
Merged
Merged
Conversation
…onnect Backport of upstream celery#10346 and celery#10345 onto the 5.6.3+gumloop_0.2.0 base. On a broker connection loss Consumer.start() calls on_close(), which wipes reserved_requests and calls AsynPool.flush(). flush() ended by clearing _busy_workers unconditionally, even for pool children still executing an accepted job. _busy_workers is the only state the fair scheduler consults (on_poll_start / schedule_writes), so after a reconnect the next received task could be written into the pipe of a child that was still mid-task and sit there until that task finished, while other children stayed idle. Clearing reserved_requests likewise let the worker_disable_prefetch gate under-count the slots in use. - AsynPool.flush(): trim _busy_workers to the inqueue fds of children that still hold an accepted job and are alive, instead of clearing the set. - Consumer.on_close(): keep active requests in reserved_requests and only drop the bookkeeping of requests that were never accepted. Regression tests from the upstream commits are included; the upstream change to the RabbitMQ quorum-queue smoke test is not (not used here).
Co-authored-by: Cursor <cursoragent@cursor.com>
Backport of the upstream assertion; click 8.5 changed the message from "No such option: --ini" to "No such option '--ini'". Co-authored-by: Cursor <cursoragent@cursor.com>
The fork inherited upstream's Blacksmith runner labels, which this org has no runners for, so every Ubuntu job sat queued until the 24h timeout. - blacksmith-4vcpu-ubuntu-* -> ubuntu-24.04 / ubuntu-22.04 - useblacksmith/setup-python -> actions/setup-python - useblacksmith/setup-docker-builder -> docker/setup-buildx-action - Codecov upload no longer fails the job (no CODECOV_TOKEN on the fork) - Integration/Smoke fan-out only on workflow_dispatch - Drop codeql-analysis.yml: the repo uses default CodeQL setup, which rejects uploads from an advanced workflow Co-authored-by: Cursor <cursoragent@cursor.com>
kombu's current release line requires Python >=3.10, so the 3.9 unit env can no longer resolve its dependencies. Upstream celery has dropped 3.9 as well; the backend runs 3.10. Co-authored-by: Cursor <cursoragent@cursor.com>
cassandra-driver has no PyPy wheel and needs ev.h to build from source (upstream's apt step already lists libev-dev). The dev Dockerfile still installed the dev requirements into a Python 3.9 interpreter, which can no longer resolve isort==7.0.0. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linear: GMLP-10778
Backport of upstream celery#10346 and celery#10345 (merged June 2026, not in any 5.6.x release) onto our
5.6.3+gumloop_0.2.0base (3e1bcb66), per the spec in the Linear comments.Root cause
On a broker reconnect
Consumer.on_close()callsAsynPool.flush(), whosefinallyblock cleared_busy_workerseven for pool children still executing an accepted task. The fair scheduler then wrote the next received task into a still-busy child's pipe, where it waited for that task to finish while other children sat idle (a 643.9s "Getting started…" stall in prod).on_close()also wipedreserved_requests, which broke ourworker_disable_prefetchgate.Changes
celery/concurrency/asynpool.py—flush()trims_busy_workersto the inqueue fds of alive children still holding an accepted job instead ofclear().celery/worker/consumer/consumer.py—on_close()keeps active requests inreserved_requestsand only drops never-accepted bookkeeping.t/unit/concurrency/test_prefork.py(+5) andt/unit/worker/test_consumer.py(+2). The upstream RabbitMQ quorum-queue smoke test change is excluded (file doesn't exist in the fork).celery/__init__.py→5.6.3+gumloop_0.2.1.Fork customizations preserved
The only fork-customized files touched are
celery/__init__.py(version string only; author/homepage kept) andt/unit/worker/test_consumer.py(additions totest_Consumeronly; the customtest_Tasks.test_ready_worker_limit_*tests are untouched).spawn.py,tasks.py(ready_worker_limit/ disable-prefetch gate),setup.py, and the spawn docs/tests have zero diff vsmain. Both ported hunks are byte-identical to upstreammain.Verification
git apply --checkof the spec's two patches against a clean3e1bcb66: clean; post-image blob hashes match the spec'sindexlines.pytest t/unit/concurrency/test_prefork.py t/unit/worker/test_consumer.py t/unit/concurrency/test_spawn.py t/unit/concurrency/test_concurrency.py→ 168 passed, 37 subtests passed.main, 5 fail (test_flush_preserves_busy_worker_for_accepted_job,…_via_scheduled_for_fallback,…_preserves_accepted_and_releases_unaccepted_together,test_on_close_purges_orphan_reservations_from_requests_dict,test_disable_prefetch_after_connection_loss_keeps_gate_closed).t/unit/worker+t/unit/concurrency: 662 passed; the one failure (test_gevent.py::test_make_killable_target,No module named 'greenlet') is environmental and fails identically onmain.uv buildproducesgumloop_celery-5.6.3+gumloop.0.2.1.tar.gzand.whl.Not in this PR (follow-ups from the spec)
python -m build && twine upload … --skip-existing, README.MD procedure).uv.lockpins the sdist, so both must be uploaded.gumloop_backend: bumpbackend/pyproject.tomltogumloop-celery==5.6.3+gumloop.0.2.1,uv lock --upgrade-package gumloop-celery, rollagent-execution-servicefirst.CI (added after the initial push)
The fork's CI had been red since it was created, independent of this change: every Ubuntu job targeted upstream's
blacksmith-*runner labels (no such runners in this org, so PR #4 andmainsat queued until the 24h timeout), andUnit (3.14, windows-latest)failed on a click 8.5 message change. Fixed here so this PR could actually be verified:t/unit/app/test_preload_cli.py: assert"No such option"(upstream's fix for click ≥8.5).blacksmith-4vcpu-ubuntu-*→ubuntu-24.04/ubuntu-22.04,useblacksmith/setup-python→actions/setup-python@v6,useblacksmith/setup-docker-builder→docker/setup-buildx-action@v3; Codecov upload no longer fails the job (fork has noCODECOV_TOKEN).workflow_dispatch.codeql-analysis.yml: the repo has default CodeQL setup enabled (it runs and passes on this PR); advanced-workflow uploads are rejected while default setup is on.docker/Dockerfile: currentkombu/isortreleases require ≥3.10 (upstream has dropped 3.9 too; the backend runs 3.10).libev-devin the apt step and dev image:cassandra-driverhas no PyPy wheel and needsev.hto build.Result: Unit 3.10–3.14 + pypy3.11 on Ubuntu, Unit 3.14 on Windows, linter, docker-build, smoke image builds, CodeQL all green.