[proxy 08/13] queue.py: bounded asyncio.Queue + worker pool + 429 backpressure #12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Spec: this implements ONE small step of #2 (the locked reliability-proxy build, aosh leg 04). Do not redesign. Stay tightly scoped to this single step.
Before you start:
git checkout main && git pullso you build on the latest landed step.Fill in
app/queue.pyand route chat requests through it.asyncio.Queue(maxsize from settings, default 100) and a worker-pool started on app startup (N workers, default 4).{messages, logical_name, future}. The route doesqueue.put_nowait(job)thenawait job['future']; a worker pops, callsapp.upstream.dispatch_chat, sets the future result/exception.asyncio.QueueFullthe route returns HTTP 429.app.obs.llm_queue_depthupdated (set toqueue.qsize()on put/get).Acceptance: a pytest enqueues a job (worker dispatching a monkeypatched upstream) and gets a result; a second test fills the queue and asserts 429.
When done:
pre-commit run --all-files(or the repo's gate) must pass, commit your work, and push to canonicalmain(this is an ephemeral feature container - finish the merge, do not leave it for a human).docs/FEATURES.mdfromplannedtolandedfor this feature, in the same push.ward agent engineer coilyco-flight-deck/agent-proxy#13 --driver goose🔒 Reserved by
ward agent --driver claude— containerengineer-claude-agent-proxy-12on hostkais-macbook-pro-2.localis carrying this issue (reserved 2026-07-02T16:44:44Z). Concurrentward agentruns are blocked until it finishes or the reservation goes stale (2h0m0s TTL);--forceoverrides.— Claude (she/her), via
ward agentWARD-OUTCOME: done - queue_maxsize default aligned to spec (100); bounded queue + worker pool + 429 backpressure verified landed on main.
Candid retrospective: this one was mostly already done when I opened the box. The bounded asyncio.Queue, the worker pool, the put-then-await-future route wiring, the QueueFull to 429 path, the llm_queue_depth accounting, and both acceptance tests had all landed earlier as part of the consolidated resilience-core commit, and FEATURES.md already read landed. So instead of building, the work was reading carefully enough to be sure nothing was missing.
The one real drift from the leg 04 step 3 spec was the default queue depth: 64 in code where the step says 100. I aligned it and left workers at the spec default of 4. I deliberately did not touch the worker calling resilience.dispatch (the spec text says upstream.dispatch_chat) because the repo evolved resilience to wrap upstream with retry/fallback/breaker, and reverting that would be a regression, not a fix. Stayed tightly scoped as asked.
What fought back: the shared container disk was at 100 percent, so pre-commit could not even create its cache dir. There is no pre-commit config in this repo anyway, so the real gate is ward test (pytest) plus ruff, both green (41 pass, lint clean). I freed cache space to be safe. Also had to rebase onto two concurrent pushes before mine landed.
Confidence is high: change is a one-line default, tests cover both the enqueue-result and fill-429 cases, tree is green on main. No follow-ups worth filing. Next step #13 (resilience validation) was already reserved remotely, so it is in flight.