Problème de concurrence avec cue flow#
Pour chaque job cue flow attribut un état, qui peut être Waiting -> Ready -> Running -> Terminated.
- Un job qui dépend d’un autre est
Waiting, - Un job qui n’a plus de dépendances (tous ses inputs sont concrets) est
Ready
À chaque cycle, flow écrit les outputs des jobs Terminated dans le contexte Cue et lit les input des jobs Ready dans le même contexte flow. Ensuite il passe les jobs Ready à Running, tous en même temps.
Il créait 1 thread par job Running (ce n’est pas configurable), et écrit et lit dans le contexte Cue en même temps. Mais Cue n’est pas thread safe donc parfois on a ce type d’erreur :
Exemple de trace#
❯ trackbone plan -c fe_bastion -n8 -t staging
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x65206f]
goroutine 84 [running]:
cuelang.org/go/internal/core/adt.(*OpContext).relNode(0xc004c93200, 0x4c93200?)
cuelang.org/go@v0.7.0/internal/core/adt/context.go:327 +0x2f
cuelang.org/go/internal/core/adt.(*FieldReference).resolve(0xc0041131e0, 0x175e920?, 0xe0?)
cuelang.org/go@v0.7.0/internal/core/adt/expr.go:703 +0x2f
cuelang.org/go/internal/core/adt.(*OpContext).unifyNode(0xc004c93200, {0x175e920, 0xc0041131e0}, 0x2)
cuelang.org/go@v0.7.0/internal/core/adt/context.go:777 +0x208
cuelang.org/go/internal/core/adt.(*OpContext).node(0xc004c93200, {0x1756800?, 0xc004199ba0}, {0x175e920?, 0xc0041131e0?}, 0x1, 0x3a?)
[....]
cuelang.org/go@v0.7.0/cue/types.go:1879 +0x11f
cuelang.org/go/cue.Value.FillPath({0xc000012540?, 0xc10473fb00?, 0x0?}, {{0x0?, 0x0?, 0x0?}}, {0x13eef40?, 0xc0ae98db90})
cuelang.org/go@v0.7.0/cue/types.go:1764 +0x9da
git.corp.caascad.com/caascad/applications/trackbone.(*Target).unify(0xc0c016d7c0, {0x13eef40?, 0xc0ae98db90}, {{0x0?, 0x0?, 0xc0c2dc79e0?}})
git.corp.caascad.com/caascad/applications/trackbone/target.go:764 +0x235
git.corp.caascad.com/caascad/applications/trackbone.(*Target).unifyOutputs(0xc0c016d7c0, {0x13c3f60?, 0x2264616373616163?}, {{0x175a650?, 0xc0cae77680?}, {0xc07ea50f10?, 0x13c3f60?}})
git.corp.caascad.com/caascad/applications/trackbone/target.go:881 +0x435
git.corp.caascad.com/caascad/applications/trackbone.(*Target).run(0xc0c016d7c0, {0x175cd10?, 0xc086dbe9b0}, {{0x175a650?, 0xc0cae77680?}, {0xc07ea50f10?, 0x7c20227070612d64?}})
git.corp.caascad.com/caascad/applications/trackbone/target.go:930 +0xf8
git.corp.caascad.com/caascad/applications/trackbone.(*Target).Run(0xc0c016d7c0, {0x175cd10, 0xc086dbe9b0}, {{0x175a650?, 0xc0cae77680?}, {0xc07ea50f10?, 0x0?}}, 0x0?)
git.corp.caascad.com/caascad/applications/trackbone/target.go:1044 +0x348
git.corp.caascad.com/caascad/applications/trackbone.Controller.runner({0xc000a987b0, 0x1, {0x0, 0x8, 0x0}, 0xc0ca2a0f00, 0xc0ca2a0f30, 0xc0f2ca9e00, 0xc0d47f3da0, 0xc0d47f3e00, ...}, ...)
git.corp.caascad.com/caascad/applications/trackbone/controller.go:389 +0x2be
created by git.corp.caascad.com/caascad/applications/trackbone.(*Controller).Run
git.corp.caascad.com/caascad/applications/trackbone/controller.go:631 +0x63a
Solution (de contournement)#
J’ai ajouté un mutex, pour réduire le nombre d’accès parallèles au contexte, mais comme flow fait également des écritures dans son coin, j'ai ajouté des wait pour lui laisser le temps de faire sa tambouille
Solution (envisageable)#
Remplacer "cue flow" par un code go plus simple (sans gestion dynamique des dépendances).
Garder cue uniquement pour la validation de la configuration et la génération des inputs pour les jobs et des dépendances mais statiquement.