Fange apper som krasjer rett etter publisering
Den 25. september ble tre publiseringer merket som vellykkede, selv om appens API krasjet sekunder inn i hver oppstart. Fordi de «lyktes», kjørte ingen tilbakerulling. En bakgrunnssjekk feilet dem noen minutter senere, og hele nettstedet gikk til en 404. Helsesjekken talte krasj i hostingplattformens hendelsesliste, som bare holder de siste fem hendelsene per maskin. En krasjløkke fyller den opp, så tellingen vokser aldri. Sjekken sammenligner nå tidspunktet for det nyeste krasjet i stedet. En publisering som krasjer i løkke, feiler, og den forrige versjonen gjenopprettes.
Hva en publisering venter på
Når du publiserer en app med backend på Mythex, rulles den nye versjonen ut til maskiner hos hostingplattformen vår. En helsesjekk avgjør om publiseringen gikk live eller feilet. Hvis den feilet, legges den forrige versjonen tilbake med en tilbakerulling.
Det vanskelige er at «startet» ikke er det samme som «svarer». Plattformen rapporterer en maskin som startet så snart den er oppe. En app som krasjer et sekund inn i oppstarten, startes umiddelbart på nytt, og et øyeblikk senere står den som startet igjen. Derfor hadde helsesjekken over tid fått flere lag:
- Se to ganger. Etter at en maskin er rapportert som startet, venter vi kort og ser igjen. Et krasj ved oppstart feiler ofte det andre blikket.
- Hold øye med krasjløkker. Hvis plattformen rapporterer at en maskin krasjet gjentatte ganger, og at den ga opp å starte den på nytt, feiler vi.
- Tell krasj siden publiseringen startet. To «startet»-blikk kan gå over en omstart. Hvis det har skjedd et krasj siden publiseringen startet, ser vi en tredje gang. Hvis det er flere krasj enn ved forrige blikk, holder ikke appen seg oppe.
Den tredje sjekken var den som feilet her.
Hvorfor tellingen ble stående stille
Krasjinformasjonen kommer fra hver maskins hendelsesliste: starter, avslutninger, omstarter. Plattformen beholder bare de siste fem hendelsene per maskin.
Tenk deg en app som krasjer 2,5 sekunder inn i hver oppstart, slik en av dem gjorde. Hver syklus legger til ett krasj og én start. Etter et par sykluser er listen full. Fra da av skyver hver ny hendelse en gammel ut. Listen glir framover, men den holder alltid omtrent samme miks: et par krasj og et par starter.
Så «hvor mange krasj siden publiseringen startet» ga samme tall ved hvert blikk. Det andre blikket så for eksempel to krasj. Det tredje blikket så også to, men andre krasj. Sjekken konkluderte med at krasjingen hadde stoppet, og godkjente publiseringen.
Det skjedde tre ganger 25. september, på to apper. Hver gang:
- ble publiseringen markert som live,
- kjørte ingen tilbakerulling, fordi ingenting hadde feilet,
- feilet vår avstemmer, en bakgrunnsjobb som sjekker deployeringer i etterkant, deployeringen noen minutter senere,
- og hele nettstedet returnerte 404.
En publisering som feiler i tide, kan gjenopprettes: tilbakerullingen legger tilbake forrige versjon. En publisering som feiler noen minutter for sent, etter å ha blitt erklært vellykket, har allerede hoppet over tilbakerullingen.
Slik fant vi det
Vi reproduserte feilen lokalt. Vi tok en fungerende API, lot den gå i dvale, og publiserte den deretter på nytt med en endring som krasjet ved oppstart. Helsesjekken markerte den som live.
Det samsvarte med produksjon. I hver av de tre publiseringene døde appen sekunder inn i hver oppstart, men krasjtellingen sjekken sammenlignet, økte aldri mellom blikkene.
Rettelsen: sammenlign det nyeste krasjet, ikke tellingen
I stedet for å telle krasj ser sjekken nå på tidspunktet for det nyeste krasjet siden publiseringen startet.
Hvis det andre blikket viser et krasj siden publiseringen startet, venter sjekken og ser en tredje gang. Hvis det nyeste krasjet i det tredje blikket er senere enn det nyeste i det andre, har maskinen krasjet igjen i mellomtiden. Den holder seg ikke oppe, og publiseringen feiler med en melding om at maskinen krasjet gjentatte ganger siden publisering og fortsatt starter på nytt.
Dette fungerer uansett hvor kort hendelseslisten er. Et glidende vindu på fem hendelser kan skjule hvor mange krasj det var, men det kan ikke skjule at et nytt nettopp skjedde. Den nyeste hendelsen er alltid den som beholdes.
Med denne endringen oppfører den lokale reproduksjonen seg riktig: publiseringen feiler, og det forrige imaget gjenopprettes. Det finnes også en test som simulerer plattformens oppførsel. Hvert blikk legger til et krasj og en start, og listen kuttes ned til fem. Testen sjekker at dommen er en feil, ikke en godkjenning.
Det vi tok med oss
- Kjenn formen på dataene du teller. En telling over en begrenset liste slutter å bety noe når listen er full. Begrensningen var ikke skjult. Vi hadde bare ikke designet sjekken rundt den.
- Foretrekk «skjedde det noe nytt?» framfor «hvor mange skjedde?» Det nyeste tidsstempelet overlever avkortning. En total gjør ikke det.
- En sen feil er verre enn en tidlig. Den samme ødelagte bygget er harmløs hvis publiseringen feiler og rulles tilbake. Den tar ned et nettsted hvis den først erklæres vellykket.
- Reproduser under ekte forhold. Feilen krevde en maskin som allerede hadde krasjet nok ganger til å fylle hendelseslisten. Ett enkelt raskt krasj i en test ville ikke ha vist den.
Denne rettelsen følger opp en annen fra samme dag, som sørget for at tilbakerullingen legger den gamle versjonen tilbake i stedet for å slette den: en mislykket republisering sletter aldri en fungerende backend. Hvis din egen app ikke publiseres fordi den krasjer ved oppstart, er feilsøkingsdokumentasjonen for publisering og vår guide om feilsøking av en AI-bygget app gode steder å starte.