Un garde qui lit un nom se contourne en renommant¶
scripts/adr/4974-attente-reinventee.pyContexte¶
Le dépôt porte Attente, qui attend une condition et dit ce qu'elle attendait en expirant. Sans
ce message, l'échec arrive plus tard sur l'assertion, qui accuse le code alors que c'est la mise en
place qui n'a pas eu lieu (ADR 2213).
L'issue #4847 a retiré treize attentes privées, et voulait clore par un cliquet sur la forme qui les
avait trouvées : private void attendre employant waitFor.
Le défaut¶
La mesure a refusé cette forme, deux fois.
Les cinq méthodes attendre restantes sont toutes légitimes : un CountDownLatch, deux
cadencements de tournage, un ralentisseur, et l'attente de mise en page devenue une enveloppe
d'Attente. Un cliquet sur ce nom les aurait toutes interdites.
Et surtout, en mesurant sans les noms, neuf réinventions vivaient sous d'autres : ouvrirLaFiche,
doubleClicVersPassage, situer, verifier. Le compte de #4847 valait 13 quand la réalité valait 22.
Décision¶
Le cliquet lit les corps, jamais les noms. Une méthode privée, quel que soit son nom et son
type de retour, dont le corps appelle WaitForAsyncUtils.waitFor, est une attente réinventée.
Attente est exemptée : elle est l'attente partagée, et compter le remède ferait monter le
cliquet à chaque fois qu'on l'enrichit.
Une aide qui attend n'est pas fautive ; ce qui l'est, c'est d'attendre sans dire quoi. Le cliquet borne donc le nombre de sites qui sondent en propre, et chaque survivant porte sa raison dans sa javadoc.
La population élargie par #4845, et pourquoi le cliquet vaut 4¶
Le cliquet a d'abord compté les méthodes privées. #4845 a montré que cette restriction ne tenait
qu'à la façon dont le défaut avait été trouvé : une attente écrite en clair dans un cas de test tait
exactement la même chose. Il compte désormais tout appel à waitFor hors d'Attente, et 41
sites y sont passés.
Une citation en commentaire n'est pas un appel : la javadoc d'AttenteAvantClic, qui explique
pourquoi elle rattrape, comptait pour une réinvention et faisait valoir un de trop au cliquet.
Les quatre survivants rattrapent tous et disent ce qu'ils attendaient :
| Site | Ce qu'il fait de l'expiration |
|---|---|
GesteVisible#amenerDansLeCadre |
lève un IllegalStateException nommant le sélecteur jamais venu |
AttenteAvantClic#attendreCliquable |
joint l'état observé de la cible |
les deux doubleClicVersPassage |
retentent trois fois, puis lèvent avec les bornes observées |
ChargementFxmlTest |
son catch (Throwable) nomme la ressource FXML fautive, ce qu'Attente ne saurait pas faire |
Et le nom a été contourné une seconde fois, par la bibliothèque. Le cliquet ne comptait que
waitFor ; waitForAsyncFx levait la même TimeoutException nue sous un autre nom, et sept sites
lui échappaient. C'est exactement le contournement que cette décision annonce, arrivé à son propre
garde. Il compte les deux depuis #4997, et Attente.surLeFil porte le geste manquant : exécuter
sur le fil, là où queSurLeFil lit sur le fil.
Les deux boucles de reprise, et pourquoi elles ne se convertissent pas¶
Les deux doubleClicVersPassage sont des boucles de reprise. Leur expiration est rattrapée pour
retenter trois fois, et c'est leur throw final qui parle, en joignant les bornes observées de la
cellule, exactement ce que l'ADR 2213 demande. Ce ne sont pas des attentes muettes.
Convertir celle de ParcoursSitesVersPassage serait pire que ne rien faire : son catch ne reçoit
qu'une TimeoutException, et l'AssertionError d'Attente sortirait au premier essai. La boucle
n'aurait plus que l'apparence d'une reprise.
Un cliquet à 0 aurait donc exigé de casser ce que le dépôt a mis trois issues à construire.
Ce qui prouve que le cliquet voit¶
Sept témoins, dont trois négatifs qui l'empêchent de tout absorber : un sleep n'est pas une
attente, waitForFxEvents n'est pas une sonde, un cas de test public n'est pas une aide.
Et un témoin qui porte la décision elle-même : renommer ouvrirLaFiche en patienter ne soustrait
rien. Sans lui, un cliquet qui lirait le nom paraîtrait juste.
Conséquences¶
- Le compte passe de 9 à 2, et les deux restants sont annotés.
- La population totale de la famille, mesurée sans les noms, valait 22 et non 15 : #4847 en a retiré 13, celle-ci 7, et 2 restent par décision.
ScenarioFicheSiteTest#ouvrirLaFicheétant converti, l'issue #4696 perd l'essentiel de son objet : son défaut restant est le clic sur une référence tenue, pas l'attente.
Alternatives écartées¶
- Le cliquet sur
private void attendre. Refusé par la mesure : il interdit cinq aides légitimes et manque neuf réinventions. C'est le dessin que #4847 proposait. - Un cliquet à 0. Il exigerait de convertir deux boucles de reprise dont l'une perdrait sa sémantique. Une décision de ne pas faire en est une.