Kapja e aplikacioneve që rrëzohen menjëherë pas publikimit
Më 25 shtator, tre publikime u shënuan si të suksesshme edhe pse API-ja e aplikacionit rrëzohej sekonda pas çdo nisjeje. Meqenëse "ishin të suksesshme", nuk u ekzekutua asnjë kthim mbrapsht; një kontroll në sfond i dështoi më pas, pak minuta më vonë, dhe e gjithë faqja shkoi në 404. Kontrolli i shëndetit po numëronte rrëzimet në listën e ngjarjeve të platformës së hostimit — e cila mban gjithmonë vetëm pesë ngjarjet e fundit për çdo makinë, kështu që një cikël rrëzimesh e mban plot dhe numërimi nuk rritet kurrë. Tani krahason kohën e rrëzimit më të fundit, dhe një publikim me rrëzime të përsëritura dështon dhe rikthen versionin e mëparshëm.
Çfarë pret një publikim
Kur publikon një aplikacion me backend në Mythex, versioni i ri vendoset në makina të platformës sonë të hostimit, dhe një kontroll shëndeti vendos nëse publikimi u bë live apo dështoi. Nëse dështoi, një kthim mbrapsht rikthen versionin e mëparshëm.
Pjesa e vështirë është që "u nis" nuk do të thotë "po shërben". Platforma e raporton një makinë si të nisur sapo ngrihet. Një aplikacion që rrëzohet një sekondë pas nisjes rinisët menjëherë, dhe një moment më vonë lexohet sërish si i nisur. Kështu kontrolli i shëndetit u bë disa shtresa me kalimin e kohës:
- Shiko dy herë. Pasi një makinë lexohet si e nisur, prit pak dhe shiko përsëri. Një rrëzim në nisje shpesh dështon shikimin e dytë.
- Kërko cikle rrëzimesh. Nëse platforma raporton se një makinë vazhdoi të rrëzohej dhe ajo hoqi dorë nga rinisja, dështo.
- Numëro rrëzimet që nga fillimi i publikimit. Dy shikime "të nisur" mund të kalojnë mbi një rinisje. Prandaj, nëse ka pasur ndonjë rrëzim që nga fillimi i këtij publikimi, shiko për herë të tretë; nëse ka më shumë rrëzime se në shikimin e mëparshëm, aplikacioni nuk po mbetet në punë.
Kontrolli i tretë është ai që dështoi këtu.
Pse numërimi mbeti i sheshtë
Informacioni i rrëzimit vjen nga lista e ngjarjeve të secilës makinë: nisje, dalje, rinisje. Platforma mban vetëm pesë ngjarjet e fundit për çdo makinë.
Merr një aplikacion që rrëzohet 2.5 sekonda pas çdo nisjeje, siç bënte një prej tyre. Çdo cikël shton një rrëzim dhe një nisje. Pas një-dy ciklesh, lista është plot. Që nga ai çast, çdo ngjarje e re shtyn një të vjetër jashtë. Lista rrëshqet përpara, por gjithmonë mban të njëjtën përzierje: një-dy rrëzime, një-dy nisje.
Kështu, "sa rrëzime pati që nga fillimi i publikimit" kthente të njëjtin numër në çdo shikim. Shikimi i dytë pa, të themi, dy rrëzime. Shikimi i tretë pa edhe dy — rrëzime të tjera, por të njëjtin numër. Kontrolli arriti në përfundimin se rrëzimet kishin mbaruar, dhe e kaloi publikimin.
Kjo ndodhi tri herë më 25 shtator, në dy aplikacione. Çdo herë:
- publikimi u shënua si live,
- nuk u ekzekutua asnjë kthim mbrapsht, sepse asgjë nuk kishte dështuar,
- reconciler-i ynë, një punë në sfond që kontrollon vendosjet pas faktit, e dështoi vendosjen pak minuta më vonë,
- dhe e gjithë faqja u kthye me 404.
Një publikim që dështon në kohë mund të rikuperohet: kthimi mbrapsht rikthen versionin e mëparshëm. Një publikim që dështon disa minuta vonë, pasi u shpall i suksesshëm, ka tashmë kapërcyer kthimin mbrapsht.
Si e gjetëm
E riprodhuam lokalisht: morëm një API që punonte, e lamë të flejë, pastaj e ripublikuam me një ndryshim që rrëzohej në nisje. Kontrolli i shëndetit e shënoi si live.
Kjo përputhej me prodhimin: në secilin nga tre publikimet, aplikacioni vdiste sekonda pas çdo nisjeje, por numri i rrëzimeve që krahasonte kontrolli nuk rritej asnjëherë mes shikimeve.
Rregullimi: krahaso rrëzimin më të ri, jo numërimin
Në vend që të numërojë rrëzimet, kontrolli tani shikon kohën e rrëzimit më të fundit që nga fillimi i publikimit.
Nëse shikimi i dytë tregon ndonjë rrëzim që nga fillimi i publikimit, kontrolli pret dhe shikon për herë të tretë. Nëse rrëzimi më i ri në shikimin e tretë është më vonë se ai më i ri në shikimin e dytë, makina u rrëzua sërish mes tyre. Nuk po qëndron në punë, dhe publikimi dështon me një mesazh që thotë se makina u rrëzua përsëri që nga publikimi dhe ende po rinisët.
Kjo funksionon pavarësisht sa e shkurtër është lista e ngjarjeve. Një dritare rrëshqitëse me pesë ngjarje mund të fshehë sa rrëzime pati, por nuk mund të fshehë që një rrëzim i ri sapo ndodhi — ngjarja më e re është gjithmonë ajo që mbahet.
Me këtë ndryshim, riprodhimi lokal sillet saktë: publikimi dështon, dhe versioni i mëparshëm rikthehet. Ka edhe një test që simulon sjelljen e platformës — çdo shikim shton një rrëzim dhe një nisje dhe e pret listën në pesë — dhe kontrollon që vendimi të jetë dështim, jo kalim.
Çfarë morëm nga kjo
- Njih formën e të dhënave që po numëron. Një numërim mbi një listë të kufizuar pushon së pari të thotë diçka kur lista mbushet. Kufizimi nuk ishte i fshehur; thjesht nuk e kishim projektuar kontrollin rreth tij.
- Preferoje pyetjen "ndodhi diçka e re?" mbi "sa ndodhën?". Vula kohore më e re mbijeton prerjen; një total nuk mbijeton.
- Një dështim i vonshëm është më keq se një i hershëm. I njëjti build i prishur është i padëmshëm nëse publikimi dështon dhe kthehet mbrapsht, dhe mund ta rrëzojë një faqe nëse shpallet i suksesshëm së pari.
- Riprodho me kushtet reale. Gabimi kërkonte një makinë që ishte rrëzuar mjaft herë për të mbushur listën e ngjarjeve. Një rrëzim i vetëm i shpejtë në test nuk do ta kishte treguar.
Ky rregullim plotësohet nga një tjetër i po atij dite, që siguroi që kthimi mbrapsht të rikthejë versionin e vjetër në vend që ta fshijë: një publikim i dështuar nuk fshin kurrë një backend që funksionon. Nëse aplikacioni yt nuk publikohet sepse rrëzohet në nisje, zgjidhja e problemeve me publikimin në dokumentacion dhe udhëzuesi ynë për debugimin e një aplikacioni të ndërtuar me AI janë vende të mira për të filluar.