Skip to content

ci: Scripts Tests (CPU) -- un worker xdist mort bloque la jambe jusqu'au plafond (14-17 min de silence apres [99%]) #16288

Description

@jsboige

Le defaut

Sur Scripts Tests (CPU), les annulations au plafond ne sont pas des runs lents coupes par le mur. Les quatre cas cites comme « depassements francs » par la PR #16087 sont des runs bloques : leur travail est termine depuis longtemps quand le plafond les tue.

Signature, sur le job de nom exact Scripts Tests (CPU) (horodatages UTC du log) :

run demarrage job derniere progression pytest node down annulation silence
34788823010 23:08:25 23:13:55 23:14:04 23:28:36 14 min
34839042549 11:47:33 11:52:10 11:51:05 12:07:44 15 min
34924561729 03:19:55 03:24:09 03:23:29 03:40:07 15 min
34934339136 05:49:58 05:55:00 05:55:13 06:10:11 15 min
34955819329 (job 104337772068, PR #16280) 10:03:49 10:07:05 ([99%]) gw3 10:06:41 / gw4 10:07:28 10:24:02 17 min

Deux faits decident la lecture :

  1. La derniere ligne de progression tombe 3,3 a 5,5 min apres le demarrage du job — dans le corps de la distribution (mediane des succes 7,3 min, mesuree par fix(ci,#15853): relever le plafond de Scripts Tests (CPU) de 20 a 30 min #16087), pas dans sa queue. [99%] signifie qu'il reste une poignee d'items.
  2. Entre cette ligne et le kill : 14 a 17 min sans une seule ligne de sortie. Ce n'est pas du travail, c'est une attente.

Le declencheur est commun et precede l'annulation : [gwN] node down: Not properly terminated. Sur le run de #16280, replacing crashed worker gw3 confirme que xdist a tente un remplacement, et gw4 est mort 47 s plus tard. La jambe ne repart jamais.

Pourquoi ce n'est pas une question de plafond

Aucun plafond ne sauve ces runs : a 30 min, les cinq auraient brule 30 min et fini cancelled de la meme facon. Relever le plafond (PR #16087) repond a un autre argument — les 2,6 min de marge au-dessus du plus long succes legitime (17,4 min) — et cet argument est fonde. Mais il ne corrige pas cette classe-ci ; il en augmente le cout.

Effet de diagnostic a noter : le plafond etant ce qui termine le blocage, la duree du job vaut exactement le plafond (20,32-20,43 min sur les quatre). Un blocage atterrit toujours sur le mur, quelle que soit la valeur du mur. La lecture « la queue de la distribution franchit le plafond » est donc un artefact de mesure : ces runs ne sont pas longs, ils sont arretes.

Ce qui manque (mesure dans le depot)

Aucun garde-fou anti-blocage dans le job :

  • l'etape Run tests (.github/workflows/scripts-tests.yml l.235-284) ne porte pas de timeout-minutes ;
  • l'invocation est pytest <13 chemins> -n 4 --dist loadscope --tb=short -q — pas de --timeout ;
  • les paquets installes sont numpy pandas scipy pyarrow pytest (l.188) et pytest-xdist (l.233) : pytest-timeout n'est pas present.

Ce que cette mesure n'etablit PAS

Pourquoi les workers meurent. OOM du runner, module qui bloque son worker, interaction avec --dist loadscope : rien ici ne tranche. Le perimetre mesure est la signature et le temps perdu, pas la cause des morts — je n'ai pas de reproduction locale (pytest-xdist absent de ma machine, et le defaut est propre a la classe de runner).

Pistes (a trancher par la mesure, pas par analogie)

piste ce qu'elle attrape limite connue
timeout-minutes sur l'etape Run tests borne le blocage doit rester au-dessus du plus long succes legitime (17,4 min) — borne donc peu sous un plafond a 30
pytest-timeout + --timeout un test qui bloque n'attrape pas une attente post-[99%] : aucun test n'est en cours, le master attend des workers morts
chien de garde sur l'ABSENCE de sortie (kill si la sortie ne progresse plus pendant N min) colle a la signature a concevoir — aucun mecanisme natif
maitriser les redemarrages de workers eviter une boucle de mort a etablir : le log de #16280 montre un remplacement effectif (replacing crashed worker gw3), la semantique de --max-worker-restart reste a mesurer avant de la citer

Critere d'acceptation propose

Un run bloque doit echouer en moins de N minutes (N proche du plus long succes legitime), avec un verdict qui nomme le worker mort et non seulement le mur. Aujourd'hui le gate nomme le plafond : c'est ce qui fait lire un blocage comme un depassement, et c'est ce qui a motive le relevement.

Liens


Mesure : lane myia-po-2023:CoursIA, 2026-09-15, en instruisant le rouge de la PR #16280.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions