Tinklaraštis

Dukart spaudus Publish, dabar publikuojama tik kartą

Trys tos pačios programėlės publikavimo užklausos pasiekė mūsų API per 84 milisekundes viena nuo kitos, ir kiekviena pradėjo pilną tos programėlės diegimą. Jos lenktyniavo dėl to paties hostingo; keletas gautų išleidimų nepavyko, nes kitas jau buvo spėjęs. Vienintelis matomas požymis buvo laiškai „release failed“ – pati programėlė galiausiai veikė. Dabar publikavimas, atėjęs kol kita publikacija tai pačiai programėlei dar vykdoma, nepradeda antro kūrimo. Duomenų bazė nusprendžia, kuri užklausa laimi, o kitoms pasakoma tiesa: publikavimas jau vyksta.

Kas nutiko

Kai publikuojate programėlę Mythex, API įrašo jai diegimą ir paprašo mūsų orkestratoriaus – paslaugos, kuri vykdo kūrimus – sukurti ir išleisti ją. Publikuoti galima iš mygtuko Publish, iš kito naršyklės skirtuko arba kai agentui pasakote publikuoti. Dvigubas paspaudimas, du skirtukai ar agento užklausa, atkeliavusi dukart, gali sukelti daugiau nei vieną tos pačios programėlės publikavimą beveik tuo pačiu metu.

Šiuo atveju trys atkeliavo per 84 ms. Kiekvienas paleido pilną diegimą. Hostingo platformoje tos pačios programėlės išleidimai buvo sukurti tą pačią sekundę, ir trys iš jų nepavyko, nes kiti jau vyko. Vėlesnis išleidimas įstrigo, o programėlė vėliau veikė.

Tai padarė klaidą lengvai nepastebimą. Vartotojas matė vieną veikiančią programėlę. Gedimai pasirodė tik laiškuose apie nepavykusį išleidimą.

Kodėl nieko nesustabdė

Publikavimo kode tikrai buvo žingsnis, kuris tikrino vykdomus projekto diegimus. Tačiau jis darė tai, kad prieš pradedant pažymėdavo kiekvieną vykdomą diegimą kaip nepavykusį – „pakeistą nauju publikavimu“. Jis buvo skirtas likučiams, kuriuos paliko nulūžęs procesas, išvalyti.

Praktiškai antras publikavimas, atėjęs kūrimo viduryje, paskelbdavo pirmąjį negyvu ir pradėdavo savo. Abu bėgo iki galo prieš tą pačią programėlę. Užrakto nebuvo; buvo žingsnis, kuris aktyviai atverdavo kelią lenktynėms.

Pirmo programėlės publikavimo atveju buvo dar keistesnis simptomas. Kai nėra nė vieno diegimo įrašo, kurį būtų galima panaudoti, du vienu metu vykstantys pirmi publikavimai bandė įterpti vieną. Duomenų bazėje yra unikalus indeksas programėlės nuorodos pavadinimui (jos slug, pavyzdžiui your-app adrese your-app.mythex.ai), todėl antras įterpimas nepavyko. API tai išvertė į „toks nuorodos pavadinimas jau užimtas“ – ragindama vartotoją pervadinti programėlę, kuri tuo metu sėkmingai publikavosi tuo pavadinimu.

Taisymas: užraktas yra pati pretenzija

Diegimo įrašo pažymėjimas dabar yra viena sąlyginė duomenų bazės atnaujinimo užklausa: paimti šią eilutę ir pažymėti ją kaip kuriamą tik tuo atveju, jei jos niekas nepublikuoja. Kadangi tai viena užklausa, duomenų bazė išsprendžia užklausas, atėjusias tą pačią milisekundę. Tiksliai vienas iš jų pakeičia eilutę. Kiti mato, kad pakeista nulis eilučių, sustoja ir niekada nepasiekia orkestratoriaus.

Užraktui taip pat reikia išeities, kai jo laikytojas miršta. Jei API perkraunama publikavimo viduryje, eilutė liktų pažymėta „building“ amžinai, ir programėlės nebūtų galima publikuoti. Todėl eilutę, kurios savininkas nebesiunčia gyvybės signalų – vykdomas publikavimas atnaujina eilutę kas 30 sekundžių, o penkios minutės tylos reiškia negyvą – galima perimti iš naujo. Ta riba kyla iš gyvybės signalo, o ne iš spėjimo, kiek trunka kūrimas. Vartotojo paties Dockerfile kūrimas gali teisėtai trukti ilgai, o lėtas kūrimas, kuris vis dar siunčia signalus, išlaiko savo pretenziją.

Žingsnis, kuris anksčiau nutraukdavo visus vykdomus diegimus prieš publikavimą, dabar nebeveikia. Išvalomos tik eilutės, kurias paliko negyvas procesas.

Pasakyti pralaimėjusiajam tiesą

Užklausa, kuri pralaimi, dabar gauna aiškų atsakymą: publish_in_progress kartu su vykstančio diegimo ID. Kiekviena vieta, kuri gali pradėti publikavimą, tai apdoroja:

  • Darbo sritis seka jau vykstantį kūrimą, o ne rodo klaidą virš jo.
  • Agentui sakoma, kad šios programėlės publikavimas jau vyksta ir reikia palaukti, o ne sakoma, kad kažkas nepavyko – anksčiau tai galėjo paskatinti jį „taisyti“ Dockerfile ir bandyti vėl.
  • Pirmo publikavimo susidūrimas dėl nuorodos pavadinimo tikrinamas: jei tą pavadinimą laiko šio projekto paties vykstantis publikavimas, atsakymas yra „jau publikuojama“, o ne „toks pavadinimas užimtas“. Tikras susidūrimas su kitu projektu vis tiek gauna pervadinimo pranešimą.

Kaip patikrinome

Parašėme atkūrimo scenarijų, kuris vienu metu paleidžia tris tos pačios programėlės publikavimus prieš tikrą duomenų bazę ir imitacinį orkestratorių, ir suskaičiuoja, kiek kūrimų orkestratoriui pavedama. Jis apima pirmą publikavimą ir gyvos programėlės perpublikavimą. Prieš pataisymą jis suskaičiavo du kūrimus, po – vieną.

Scenarijus apima ir atsarginį kelią: pažymi programėlės eilutę kaip kuriamą be gyvybės signalo dešimt minučių, publikuoja dar kartą ir tikrina, ar naujas publikavimas perima eilutę ir paleidžiamas.

Vienetų testai užrakto dvi pareigas: iš trijų vienu metu vykstančių perpublikavimų tiksliai vienas praeina, o kiti du gauna pranešimą, kad publikavimas vykdomas; ir kūrimą, kurio savininkas žuvo, galima perimti. Kitas testas tikrina, kad naujas bandymas nepaveldi ankstesnio bandymo klaidos pranešimo.

Ką iš to išmokome

  • Valymo kodas gali būti lenktynės apsirengęs. „Nutraukti viską, kas vyksta, tada pradėti“ atrodo kaip higiena. Su dviem iškvietėjais tai kiekvienas nutraukia kitą.
  • Leiskite duomenų bazei spręsti. Skaitymas, po kurio seka rašymas, palieka tarpą kitai užklausai. Viena sąlyginė atnaujinimo užklausa to nedaro.
  • Kiekvienas užraktas turi galiojimo pabaigą, susietą su gyvumu. Be jos avarija virsta įstrigusia programėle.
  • Klaidų pranešimai yra nurodymai. „Tas pavadinimas užimtas“ vartotojus skatino daryti ne tai. Teisingas pranešimas buvo paprastesnis ir teisingas.

Daugiau apie publikavimą dokumentuose: kaip publikuoti. Ir susijęs pataisymas: jūsų publikuota programėlė lieka veikianti, kol ją perpublikuojate.

Mythex · Pricing · Kurkite bet ką su dirbtiniu intelektu · Svetainių ir programėlių šablonai · Mythex palyginimas · Programėlių kūrimo su dirbtiniu intelektu žodynėlis · Nemokami programėlių kūrimo su dirbtiniu intelektu įrankiai · English

English አማርኛ العربية Български বাংলা Bosanski Català Čeština Dansk Deutsch Ελληνικά Español Español (España) Eesti فارسی Suomi Français Français (Canada) ગુજરાતી हिन्दी Hrvatski Magyar Հայերեն Bahasa Indonesia Íslenska Italiano 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Latviešu Македонски മലയാളം Монгол मराठी Bahasa Melayu မြန်မာ Norsk bokmål Nederlands ਪੰਜਾਬੀ Polski Português (Brasil) Português (Portugal) Română Русский Slovenčina Slovenščina Soomaali Shqip Srpski Svenska Kiswahili தமிழ் తెలుగు ไทย Tagalog Türkçe Українська اردو Tiếng Việt 简体中文 繁體中文(香港) 繁體中文(台灣)