Une attente qui lit le graphe de scène le lit sur le fil JavaFX, ou elle lit ce qu'un autre écrit¶
scripts/adr/5278-attente-hors-du-fil.pyLe contexte¶
Attente.queSurLeFil existe depuis #4408, et sa javadoc dit sa raison :
Un prédicat qui touche le graphe de scène doit être lu sur le fil FX, qui n'est pas partageable : sinon il lit un graphe qu'un autre fil est en train d'écrire.
Le patron n'a pas essaimé. Mesure du 2026-09-05 : 138 appels à Attente.que ou queSurLeFil,
dont huit sur le fil, et 63 qui lisent le graphe depuis le fil du test, dans 31 classes.
Ce que cela produit¶
RetourApresVerificationE2ETest.depuis_multisite_la_verification_se_propage a levé en CI :
Son prédicat lisait les getItems() d'une TableView que le chargement asynchrone remplaçait. Un
index égal à la longueur est la signature d'une lecture concurrente, pas d'un décalage
applicatif.
Le banc figure au relevé des bancs instables : deux chutes en tête sur 884 tirages, trois de plus comme victime. Il n'est pas seul, et c'est ce que le cliquet compte.
La décision¶
Un prédicat d'attente qui lit le graphe de scène se lit sur le fil JavaFX, ou son site est compté par un cliquet qui descend.
Le cliquet plutôt que l'invariant, parce que la population est de 63 dans 31 classes et que la convertir d'un coup ferait une demande qu'aucune relecture ne tiendrait. Il s'est ouvert à 63. Le lot #5269 l'a descendu à 31 en convertissant les trente-deux sites des bancs que le relevé accuse, et #5279 à zéro en traitant les trente et un restants. Le cliquet à zéro n'est pas un invariant déguisé : une attente qu'on ajouterait sans pouvoir la lire sur le fil reste possible, en relevant le cliquet ici, c'est-à-dire en écrivant pourquoi.
La règle se dérive des lectures de nœuds : lookup(, queryAs, getItems(), getScene(),
getChildren(), getText(). Énumérer les classes fautives donnerait une liste à tenir à la main, qui
dérive de ce qu'elle décrit sans que rien ne rougisse. L'ADR 5258 vient de mesurer ce défaut sur une
autre population du même dépôt.
Ce que la décision ne dit pas¶
Elle n'ordonne pas la conversion de chaque site. queSurLeFil fait un aller-retour sur le fil FX
à chaque tour de boucle. Là où le prédicat ne touche le graphe que par un chemin sûr, la conversion
coûterait sans rien tenir. Le garde compte ; le jugement reste au site, et un site laissé en que
écrit sa raison plutôt que de sortir du compte en silence.
La décision est plus large que son garde, et l'écart se déclare. Un WaitForAsyncUtils.waitFor
nu portait la même faute et lui échappait ; le dépôt en avait un fautif,
AttenteAvantClic.attendreCliquable (#5330). Cette limite était tue, et c'est ce silence qui a
laissé le site invisible : une limite qu'on ne déclare pas se lit comme une couverture.
Et une seconde fois en #5353 : le garde ne suivait pas un prédicat qui délègue à une aide de son fichier, au motif que « le motif attrape déjà la population entière ». C'était faux - trente-neuf sites - et une limite dont l'argument ne tient pas se lit, elle aussi, comme une couverture.
Une troisième en #5430 : une accolade dans une chaîne tronquait le corps d'une aide, cachant son
lookup(. La lecture passe à la structure.
Elle ne change rien au comportement de Attente sur une exception. lireSurLeFil re-lève
délibérément un prédicat qui a levé, et sa raison est écrite dans le code : « le taire ferait expirer
l'attente sur un délai, en accusant la lenteur là où il y a une exception ». Cette décision-ci la
confirme au lieu de la défaire. L'hypothèse inverse avait été écrite en ouvrant #5269, et elle était
fausse.
Pourquoi l'article A2¶
« Un garde est vu rouge sur sa propre mutation. » Une attente qui lit le graphe hors du fil est un dispositif qui ne peut pas rougir de façon fiable : il rend vrai, faux, ou lève, selon la vitesse de la machine. Un banc dont le verdict dépend de l'ordonnancement n'a pas été vu rouge sur ce qu'il prétend attraper, il a été vu vert le plus souvent.
Les alternatives écartées¶
Allonger les délais. C'est le remède qui a l'air de marcher : le banc redevient vert parce que la fenêtre de course se referme plus souvent. Il ne supprime pas la lecture concurrente, il la rend plus rare, et il ralentit la suite pour tout le monde.
Avaler l'exception du prédicat. Elle ferait expirer l'attente sur un délai et accuserait la lenteur là où il y a une faute de fil. C'est la décision que #4408 a déjà prise dans l'autre sens.