internal/dispatcher/agent : la base est fermée sous les workers, panic intermittent en test #47
Labels
No labels
bug fix
feature implementation
new feature
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
syonad/two#47
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?
Symptôme
go test ./...échoue de façon intermittente surinternal/dispatcher/agent:Reproduit sur
main(10c9bc2), go1.24.11, darwin/arm64 : environ une passe complète surdeux. Le paquet seul (
go test -count=12 ./internal/dispatcher/agent/) passe toujours — c'estl'exécution des paquets en parallèle qui le fait sortir.
Trace
Le canal fermé est celui de Badger, pas celui de
Queue.queue.go:45n'est que la frameoù la tâche s'exécute.
Cause
internal/dispatcher/agent/helpers_test.go:La queue est démarrée mais jamais arrêtée. À la fin du test,
db.Close()s'exécute alorsque les deux goroutines worker peuvent encore être en train d'exécuter une tâche dispatchée ;
celle-ci appelle
state.Set→kv.AddInDB→ écriture Badger sur une base fermée.C'est exactement l'inversion de l'invariant documenté au CLAUDE.md — serveurs HTTP → drainage
des workers →
db.Close()— mais commise dans le harnais de test.Effet de bord secondaire : les goroutines worker fuient d'un test à l'autre dans ce paquet,
ce qui explique que le défaut ne sorte que sous la charge d'une passe complète.
Ce qui n'est pas touché
La production est correcte.
cmd/agent/main.gorespecte l'ordre :shutdown()arrête lesserveurs HTTP, appelle
q.Stop(), etdb.Close()n'est atteint qu'au retour du drainage(
main.go:45). Le défaut est confiné au test.Il n'y a donc pas de course à l'arrêt de l'agent — seulement une suite de tests qui échoue une
fois sur deux, ce qui est suffisamment pénible pour être corrigé : une CI rouge par
intermittence finit par ne plus être lue.
Correction proposée
Arrêter la queue avant de fermer la base dans
newTestDispatcher:Queue.Stoprejette les nouvelles tâches puis attend les tâches en vol (wg.Wait()), ce quigarantit qu'aucune écriture n'est en cours quand Badger se ferme. Il faut donc construire la
queue avant d'enregistrer le cleanup.
À faire avant #46, qui touchera ce paquet.
Toujours présent le 2026-10-04 — et aussi sur le paquet lancé seul
Constaté en vérifiant E2 de #50 : une passe de
go test ./...a échoué surinternal/dispatcher/agent, avec exactement la trace du ticket (panic: send on closed channeldans
badger.(*DB).sendToWriteCh, depuisstate.Setappelé parDispatcher.Dispatch.func1).Reproduit ensuite sur
main(01c67bd), sans aucun changement, go1.25.14, darwin/arm64 :→ 1 échec sur 6. Contrairement à ce que dit le ticket, le paquet lancé seul le fait donc
sortir aussi : le parallélisme de la suite complète augmente la fréquence, il n'est pas nécessaire.
Le passage à go 1.25 (#46) n'a rien changé au défaut.
Rien de neuf sur la cause : la queue démarrée par
helpers_test.gon'est jamais arrêtée avantdb.Close().