Repository navigation
feat(admission): count workers still running after their caller was cancelled (#728, slice 2) - #903
Conversation
…ancelled (#728, slice 2) A cancelled tool call leaves its asyncio.to_thread worker running; slice 1 (#885) kept its admission slot and logged its outcome, but nothing said how many such workers were still running or how the ended ones did. handlers/abandoned_work counts, per tool, the abandoned workers in flight and the outcome of each one that ended (completed / raised / cancelled). run_admitted records the abandonment, and _log_abandoned records the outcome and names in its log line how many abandoned workers of the tool remain. Refs #728
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Claude finished @cdeust's task in 2m 50s —— View job Review of PR #903: approve, no Blockers
None of the five reviews found a Blocker. The summary, with 3 Notes and no action needed before merge, is here. The previous Pipeline run on this PR passed, and a new one is in progress. I couldn't run tests, ruff or the craftsmanship gate in this job because those commands need approval. Verdict: approve |
Review 1/3 (ADR-1119): PR #903Five foreground reviews ran: quality, security, performance, tests and docs. None found a Blocker.
Notes, no action before merge
Verdict: approve |
#903 (540df96) brought abandoned_work, the same registry as worker_ledger. Keep main's admission.py, drop worker_ledger and its tests, and have memory_stats return abandoned_work.snapshot() as abandoned_workers. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018kyZYtgfAGUYWDSLAfQPUp
…pletion (#728, slice 5) (#946) * docs(admission): ADR-1125, a cancelled tool call's worker runs to completion (#728, slice 5) Issue #728 asks to keep work counted "until completion or a documented cooperative cancellation boundary". Slices 1-4 (#885, #903, #902, #936, #943) implement and prove the first: the slot is released by the worker's done callback, the caller awaits through asyncio.shield, abandoned workers are reported in memory_stats.abandoned_workers. Nothing forwards the cancellation into the worker thread, so no cooperative boundary exists. ADR-1125 records those semantics, amends ADR-0329 (the slot belongs to the worker), states what a handler that wants to stop early must specify, and lists the tests that hold each point. Mirror regenerated with wiki_decision_mirror.generate_mirror. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_018kyZYs8nydviS39BjwT88E * fixup! docs(admission): ADR-1125, a cancelled tool call's worker runs to completion (#728, slice 5) --------- Co-authored-by: Claude <[email protected]>
Summary
Tranche 2 de #728 : rendre lisible l'état des workers qui continuent après l'annulation de leur appelant.
asyncio.to_threadne peut pas arrêter un thread en cours. La tranche 1 (#885) garde donc le créneau d'admission jusqu'à la fin du worker et journalise son issue. Mais rien ne disait combien de ces workers tournaient encore, ni comment les autres avaient fini. Le nouveau modulemcp_server/handlers/abandoned_work.pycompte, par outil, les workers abandonnés encore en vol (in_flight) et l'issue de chacun de ceux qui ont fini (ended: completed / raised / cancelled).run_admittedenregistre l'abandon, et_log_abandonedenregistre l'issue et indique dans sa ligne de log combien de workers abandonnés de l'outil restent en cours.Refs #728 (pas
Closes: critère « Define and report in-flight mutation status » couvert seulement pour la définition et le log, voir plus bas)Type of change
Test plan
tests_py/handlers/test_abandoned_work_status.py(nouveau, 4 tests, ordonnancement parthreading.Event, aucun verdict ne dépend du temps écoulé) : un worker abandonné compte dansin_flightjusqu'à sa fin ; chaque issue est comptée à part ; un appelant qui attend n'est jamais compté ; deux issues identiques s'additionnent, et le log décompte (1 puis 0 encore en cours). Rouges sans le changement deadmission.py(3 sur 4 échouent ; le 4e vérifie qu'un appelant qui attend n'est pas compté).tests_py/handlers/test_admission_cancellation.py: les messages de log attendus portent le décompte.pytest tests_py/handlers tests_py/server tests_py/invariants/test_I10_pool_capacity.py: 1848 passés, 82 ignorés (PostgreSQL absent ici).GITHUB_BASE_REF=main python scripts/ci_mutation_diff.py, mutmut 3.8.1) : 2 fichiers, 0 échec, 0 non testé. Un premier essai avait trouvé un survivant dansrecord_ended(deux issues identiques jamais testées) ; le testsame_outcome_adds_upl'a tué.ruff checketruff format --checksur les fichiers modifiés : OK.python scripts/check_craftsmanship.py: OK.Audit notes
memory_statsdans cette PR. Le premier essai y ajoutaitabandoned_workà la réponse, mais modifierhandlermet toute la fonction dans le périmètre du gate de mutation, et 58 mutants préexistants y survivent (champs de la réponse non vérifiés partest_memory_stats.py). Cette exposition client fait l'objet d'une tranche à part.Breaking changes
Aucun. Seul changement visible : la ligne de log
WARNINGd'un worker abandonné se termine désormais par(N abandoned still running).Generated by Claude Code