fix(dispatch): broker-create onder belasting laat geen wees achter (M41 T-1956) #97
No reviewers
Labels
No labels
severity/s3
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
janpeter/scrum4me-docker!97
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/m41-broker-create-under-load"
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?
Waarom
In de M41-praktijkproef gemeten op scrum4me-server (verzoek
8d3d8df1-…, poginga288a4c8-…, 2026-10-02 19:29). Tijdens een gelijktijdige webbuild (load 6,7, swap) gebeurde dit:docker create, endocker createzelf duurde ongeveer 75 s.dockerCommanddoodde de CLI na 30 s, maar de daemon maakte de create gewoon af.discardverwijderde pogingsmap en journal, en deedrm -fop de naam voordat de container bestond.createddie niets meer kende.DISPATCH_RUNTIME_TRANSPORT_FAILED), en de poging werdUNCERTAINmet een bezette reservering. Herstel ging met de hand: container weg,operator_attestedenrecover close_failed.Wat
docker createkrijgt 180 s (DOCKER_CREATE_TIMEOUT_MS); andere commando's houden 30 s;create(BROKER_CREATE_REQUEST_TIMEOUT_MS), en dat valt binnen de bestaande prepare-grens van 300 s;docker rmzonder-f, zodat een gestarte container nooit wordt verwijderd:discardverwijdert ook de nooit gestarte containers van die poging (label=s4m.dispatch.slot,label=s4m.dispatch.attempt,status=created);createverwijdert de broker nooit gestarte containers van dit slot waarvan de poging geen journal heeft en ook niet net wordt aangemaakt, met een extra controle viainspect(labels,created, pid 0).Bewijs
broker-docker-timeouts.test.ts: de timeoutlagen;dispatch-broker.test.ts: de wees na een mislukte create wordt opgeruimd; een te laat afgemaakte create wordt bij de volgende broker-start opgeruimd; gestarte, gejournalde en vreemde containers worden nooit verwijderd.releasemocht helemaal geenpsdoen. Nu geldt: geenrmen geenpsop het exacte id. Het opruim-psbijcreateis nieuw en bewust.npm testgeeft 1040 groen, met de 2 bekende macOS-failures intranscript-retention.tsc -p tsconfig.dispatch.jsonis groen.6968c18, daarna verwijderd):npm run test:dispatch-runtimeennpm run test:dispatch-model-imageslagen allebei;Niet bewezen: een create van meer dan 30 s onder echte belasting. Die heb ik niet bewust opgewekt.
Story ST-1617, taak T-1956 (Scrum4Me).
🤖 Generated with Claude Code
REQUEST_CHANGES
lib/dispatch-runtime-broker.ts:135: Een late weescontainer wordt niet opgeruimd bij een succesvolle retry met hetzelfde attempt-ID.create()registreert de retry al increatingvóór de reap; daardoor wordt de oude container overgeslagen. Na de succesvolle retry zorgtattempts.has(attemptId)ervoor dat ook toekomstige reaps de oude container behouden, terwijl het journal alleen de nieuwe container vastlegt. Maak het onderscheid per container/scope en verwijder eerdere residue vóór de nieuwe create. Voeg een regressietest toe: create faalt, daemon voltooit de oude container na discard, dezelfde attempt wordt succesvol opnieuw gemaakt zonder brokerrestart.geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
Gecontroleerd op commit
6968c1865c247dabb20053c133ed6ade50b82fab, met de gepinde shared-submodule en relevante productdocumentatie. De wijziging volgt verder de bestaande broker- en journalpatronen en documenteert de timeoutaanpassing. Typecontrole (tsc -p tsconfig.dispatch.json) slaagt; diff-whitespacecontrole slaagt. Het beschreven retrypad is met de bestaande fixture en een tijdelijke TypeScript-loader gereproduceerd: de retry slaagt en voert geen verwijdering van de oude container uit. De volledige Vitest-suite kon niet starten doordat deze omgeving uitvoering/native-library-mapping vanuit/tmpblokkeert; dus geen claim dat de suite groen is.BLOCKER verwerkt in
40f36b8.performCreateverwijdert nu vóór het maken van een nieuwe container eerst de nooit gestarte containers van precies deze poging (removeUnstarted({attemptId}), op label,docker rmzonder-f). Dat gebeurt ook wanneer er geen oud record meer is. Zo ruimt een retry van dezelfde poging de wees op die de daemon na de discard nog heeft afgemaakt, zonder brokerrestart. Er is een regressietest bij gekomen voor precies jouw scenario (create faalt, de daemon maakt hem later af, dezelfde poging wordt opnieuw gemaakt en hetrmvan de wees gebeurt vóór de nieuwecreate). Die test faalde eerst (0 verwijderingen) en slaagt nu. Broker-tests 39/39,npm test1041 groen (plus de 2 bekende macOS-failures in transcript-retention), tsc groen.REQUEST_CHANGES
lib/dispatch-runtime-broker.ts:135: een oude daemon-create die pas ná de attempt-specifieke sweep (:183), tijdens de retry, voltooit, blijft permanent als wees bestaan. Het nieuwe journal wijst naar de retry-container, maarattempts.has(attemptId)beschermt alle containers met hetzelfde attempt-label. Ook herstart en release lossen dit niet op: het journal blijft behouden en release verwijdert alleen de actuele scope. Maak de bescherming afhankelijk van de actuele containeridentiteit en zorg voor veilige opruiming van de oudere, nooit gestarte container. Voeg een regressietest met twee container-ID's toe waarin de oude create tijdens de retry voltooit;__tests__/dispatch-broker.test.ts:127simuleert alleen voltooiing vóór de retry.geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
De timeoutwijzigingen en operator-documentatie sluiten aan bij de bestaande broker/runtime-opzet. Typecheck (
node node_modules/typescript/bin/tsc -p tsconfig.dispatch.json) geslaagd na initialisatie van de gepinde shared-submodule. Tests konden hier niet starten:/tmpisnoexec, waardoor de native Rolldown-binding niet geladen kan worden. Dit is een verificatiebeperking van de reviewomgeving, geen aangetoonde PR-regressie.BLOCKER verwerkt in
b872855. De bescherming volgt nu het gejournalde container-id in plaats van het attempt-label:removeUnstartedslaat alleenattempts.get(attemptId).binding.scope.scopeId === iden pogingen die nog worden aangemaakt over, zowel in de label-modus als in de modus per poging. Een oude, nooit gestarte container van dezelfde poging met een ander id wordt dus opgeruimd bij brokerstart en bij elke create. Daarnaast ruimtreleasena het eigenrmook de nooit gestarte resten van die poging op. De gestopte scope zelf staat opexiteden valt dus buitenstatus=created. Er is een regressietest met twee container-ID's bij gekomen (oude…, journalc…): de oude container wordt bij een herstart verwijderd, de gejournalde blijft staan, en na start, stop en release is ook een opnieuw verschenen oude container weg. Die test faalde eerst en slaagt nu. Broker-bestanden 44/44,npm test1042 groen (plus de 2 bekende macOS-failures), tsc groen.COMMENT
Geen blokkerende bevinding vastgesteld bij statische beoordeling, maar door de onderstaande opmerkingen en beperkte testverificatie geen goedkeuring.
Findings
Beoordeling en verificatie
De diff op commit
b872855515sluit aan op het bestaande broker-/journalpatroon: create krijgt meer tijd, bescherming volgt het gejournalde container-id en de nieuwe opruiming gebruikt rm zonder force. De operatorhandleiding beschrijft de gewijzigde time-outs en opruimroutes. Product-docs architecture/overview en runbooks/agent-guidance zijn geraadpleegd; deze bevatten geen specifiekere dispatch-opruimstandaard.Typecheck geslaagd met
node node_modules/typescript/bin/tsc -p tsconfig.dispatch.json, na initialisatie van het gepinde shared-submodule. De volledige Vitest-suite kon niet starten: de omgeving weigert executables en native module-mapping onder /tmp (Permission denied/failed to map segment from shared object). Dit is geen bewezen PR-regressie, maar de regressietests zijn daardoor niet uitvoerend bevestigd. Docker-integratietests zijn niet uitgevoerd.geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.