Detectar les apps que es bloquegen just després de publicar
El 25 de setembre, tres publicacions es van marcar com a reeixides tot i que l'API de l'app es bloquejava segons després de cada arrencada. Com que «van reeixir», no es va executar cap reversió; una comprovació de fons les va fer fallar uns minuts més tard, i tot el lloc va passar a un 404. La comprovació de salut comptava els bloqueigs a la llista d'esdeveniments de la plataforma d'allotjament, que només guarda els últims cinc esdeveniments per màquina, de manera que un bucle de bloquejos l'omple i el recompte mai no creix. Ara compara l'hora del bloqueig més recent, i una publicació amb bucle de bloquejos falla i restaura la versió anterior.
Què espera una publicació
Quan publiques una app amb backend a Mythex, la nova versió es desplega a màquines de la nostra plataforma d'allotjament, i una comprovació de salut decideix si la publicació ha quedat en línia o ha fallat. Si ha fallat, una reversió restaura la versió anterior.
La part difícil és que «arrencat» no és el mateix que «servint». La plataforma informa que una màquina està arrencada tan bon punt és en marxa. Una app que es bloqueja un segon després d'arrencar es torna a iniciar immediatament, i un moment després torna a aparèixer com a arrencada. Així que la comprovació de salut s'havia anat complicant amb el temps en diverses capes:
- Mira dues vegades. Després que una màquina aparegui com a arrencada, espera una estona i torna a mirar. Un bloqueig en arrencar sovint falla la segona mirada.
- Vigila els bucles de bloquejos. Si la plataforma informa que una màquina no ha parat de bloquejar-se i que ha deixat de reiniciar-la, falla.
- Compta els bloquejos des que va començar la publicació. Dues mirades de «arrencat» poden creuar-se amb un reinici. Així que si hi ha hagut algun bloqueig des que va començar aquesta publicació, es mira una tercera vegada; si hi ha més bloquejos que en la mirada anterior, l'app no es manté en marxa.
La tercera comprovació és la que va fallar aquí.
Per què el recompte es quedava igual
La informació de bloquejos prové de la llista d'esdeveniments de cada màquina: inicis, sortides, reinicis. La plataforma només guarda els últims cinc esdeveniments per màquina.
Imagina una app que es bloqueja 2,5 segons després de cada arrencada, com una de les que hi havia. Cada cicle afegeix un bloqueig i un inici. Després de un parell de cicles, la llista està plena. A partir d'aquí, cada esdeveniment nou fa sortir un de vell. La llista avança, però sempre conté aproximadament la mateixa barreja: un parell de bloquejos i un parell d'inicis.
Així que «quants bloquejos des que va començar la publicació» retornava el mateix nombre en cada mirada. La segona mirada veia, posem per cas, dos bloquejos. La tercera també veia dos —bloquejos diferents, però el mateix recompte—. La comprovació concloïa que els bloquejos havien parat, i aprovava la publicació.
Això va passar tres vegades el 25 de setembre, en dues apps. Cada vegada:
- la publicació es va marcar com a en línia,
- no es va executar cap reversió, perquè no havia fallat res,
- el nostre reconciliador, una tasca de fons que comprova els desplegaments a posteriori, va fer fallar el desplegament uns minuts més tard,
- i tot el lloc va retornar un 404.
Una publicació que falla a temps es pot recuperar: la reversió restaura la versió anterior. Una publicació que falla uns minuts tard, després d'haver estat declarada com a reeixida, ja ha saltat la seva reversió.
Com ho vam trobar
Ho vam reproduir en local: vam agafar una API que funcionava, la vam deixar adormir, i després la vam republicar amb un canvi que es bloquejava en arrencar. La comprovació de salut la va marcar com a en línia.
Això coincidia amb producció: en cada una de les tres publicacions, l'app morís segons després de cada arrencada, però el recompte de bloquejos que la comprovació comparava mai no pujava entre mirades.
La correcció: comparar el bloqueig més recent, no el recompte
En lloc de comptar els bloquejos, la comprovació ara mira l'hora del bloqueig més recent des que va començar la publicació.
Si la segona mirada mostra qualsevol bloqueig des que va començar la publicació, la comprovació espera i mira una tercera vegada. Si el bloqueig més recent en la tercera mirada és posterior al bloqueig més recent de la segona, la màquina s'ha tornat a bloquejar entremig. No es manté en marxa, i la publicació falla amb un missatge que indica que la màquina s'ha bloquejat repetidament des de la publicació i encara està reiniciant-se.
Això funciona sigui quina sigui la mida de la llista d'esdeveniments. Una finestra lliscant de cinc esdeveniments pot amagar quants bloquejos hi ha hagut, però no pot amagar que n'acaba de passar un de nou: l'esdeveniment més recent és sempre el que es conserva.
Amb aquest canvi, la reproducció local es comporta correctament: la publicació falla i es restaura la imatge anterior. També hi ha una prova que simula el comportament de la plataforma —cada mirada afegeix un bloqueig i un inici i retalla la llista a cinc— i comprova que el veredicte sigui un fracàs, no un èxit.
Què n'hem après
- Coneix la forma de les dades que comptes. Un recompte sobre una llista limitada deixa de voler dir res quan la llista està plena. El límit no estava amagat; simplement no havíem dissenyat la comprovació tenint-lo en compte.
- Prefereix «ha passat alguna cosa nova?» a «quantes coses han passat?». L'hora més recent sobreviu al retall. Un total no.
- Un fracàs tardà és pitjor que un de primerenc. El mateix build trencat és inofensiu si la publicació falla i es reverteix, i tomba un lloc si primer es declara com a reeixit.
- Reprodueix amb les condicions reals. L'error necessitava una màquina que ja s'hagués bloquejat prou vegades per omplir la seva llista d'esdeveniments. Un únic bloqueig ràpid en una prova no l'hauria mostrat.
Aquesta correcció es complementa amb una altra del mateix dia, que va fer que la reversió restauri la versió antiga en lloc d'eliminar-la: una republicació fallida mai no esborra un backend que funciona. Si la teva pròpia app no es pot publicar perquè es bloqueja en arrencar, la documentació de resolució de problemes de publicació i la nostra guia sobre depurar una app construïda amb IA són bons llocs per començar.