Блог

Двоен притисок на Publish сега објавува еднаш

Три барања за објавување на иста апликација стигнаа до нашиот API на 84 милисекунди едно од друго, и секое стартуваше цело распоредување на таа апликација. Се трките едно со друго на истиот хостинг, неколку од добиените издања не успеаја бидејќи друго веќе било пред нив, а единствениот видлив знак беше е-пошта „release failed“ — самата апликација на крајот беше во ред. Сега, објавување што ќе пристигне додека друго за истата апликација веќе работи не стартува втора изградба. Базата одлучува кое барање ќе победи, а останатите добиваат вистински одговор: објавување веќе се извршува.

Што се случи

Кога ќе објавите апликација на Mythex, API-то запишува распоредување за неа и го бара од нашиот оркестратор — услугата што ги извршува изградбите — да ја изгради и издаде. Објавувањето може да започне од копчето Publish, од друг таб на прелистувачот или од агентот кога ќе го замолите за тоа. Двоен клик, два таба или барање на агентот што ќе стигне двапати можат да предизвикаат повеќе објавувања за иста апликација во речиси исто време.

Во овој случај, три стигнаа во рок од 84 ms. Секое стартуваше цело распоредување. На платформата за хостинг, издањата за истата апликација беа создадени во истата секунда, а три од нив не успеаја бидејќи другите веќе беа во тек. Едно подоцнежно издание заглавило, а апликацијата потоа работеше.

Тоа го правеше лесно за пропуштање. Корисникот виде една работечка апликација. Неуспесите се појавуваа само како е-пошти за неуспешно издание.

Зошто ништо не го спречи

Кодот за објавување имаше чекор што ги гледаше распоредувањата во тек за проектот. Но, тој чекор пред стартување ги означуваше сите распоредувања во тек како неуспешни — „superseded by a new publish“. Требаше да ги чисти изградбите што ги оставил процес што паднал.

Во пракса, второ објавување што ќе стигне додека трае изградба, го прогласуваше првото за мртво и стартуваше свое. И двете се извршуваа до крај против истата апликација. Немаше заклучување; имаше чекор што активно го чистеше патот за трка.

Имаше и втор, почуден симптом за првото објавување на една апликација. Бидејќи уште немаше запис за распоредување за повторна употреба, две истовремени први објавувања обидуваа да вметнат еден. Базата има единствен индекс на линк-името на апликацијата (нејзиниот slug, како your-app во your-app.mythex.ai), па второто вметнување не успеа. API-то го преведуваше тоа во „тоа име на линк е зафатено“ — и го советуваше корисникот да ја преименува апликација што во тој момент успешно се објавуваше под тоа име.

Поправката: барањето е заклучувањето

Заклучувањето на записот за распоредување сега е единствено условно ажурирање во базата: земи го овој ред и означи го како во изградба само ако никој не го објавува. Бидејќи е една наредба, базата ги решава барањата што стигнуваат во иста милисекунда. Точно едно од нив го менува редот. Останатите видат дека нула редови се променети, застануваат и никогаш не стигнуваат до оркестраторот.

Заклучувањето исто така треба излез кога неговиот носител ќе умре. Ако API-то се рестартира во средина на објавување, редот би останал означен како „building“ засекогаш и апликацијата не би можела да се објави. Затоа, ред чиј сопственик повеќе не испраќа heartbeat — тековното објавување го ажурира редот на секои 30 секунди, а пет минути тишина се сметаат за мртво — може повторно да се земе. Тој праг доаѓа од heartbeat-от, а не од погодување колку трае изградбата. Изградба на сопствениот Dockerfile на корисникот може легитимно да трае долго, а бавна изградба што сè уште праќа heartbeat го задржува своето заклучување.

Чекорот што ги означуваше како неуспешни сите распоредувања во тек веќе не се извршува пред објавување. Се чистат само редовите што ги оставил мртов процес.

Кажување на губитникот вистината

Барањето што губи сега добива јасен одговор: publish_in_progress, заедно со ИД-то на распоредувањето што работи. Секое место што може да стартува објавување го обработува:

  • Работниот простор го следи веќе работечката изградба, наместо да прикаже грешка преку неа.
  • Агентот добива порака дека објавување на оваа апликација веќе работи и дека треба да го почека, наместо да му се каже дека нешто не успеало. Порано тоа можеше да го испрати да „поправа“ Dockerfile и да пробува повторно.
  • Судирот при прво објавување на линк-името се проверува: ако редот што го држи името е тековното објавување на овој проект, одговорот е „already publishing“, а не „тоа име е зафатено“. Вистински судир со друг проект сè уште ја добива пораката за преименување.

Како го проверивме

Написавме скрипта за репродукција што истовремено извршува три објавувања на една апликација против вистинска база и лажен оркестратор, и брои колку распоредувања бара оркестраторот. Ги покрива и првото објавување и повторно објавување на жива апликација. Пред поправката, бројот беше два. После неа, еден.

Скриптата го покрива и излезот за крајни случаи: го означува редот на апликацијата како во изградба без heartbeat десет минути, повторно објавува и проверува дали новото објавување го зема редот и се извршува.

Единечните тестови го држат заклучувањето на двете работи што ги мора: од три истовремени повторни објавувања точно едно минува, а другите две добиваат порака дека објавување работи; и изградба чиј сопственик умрел може да се земе. Друг тест проверува дека нов обид не ја носи грешката од претходниот обид.

Што научивме

  • Кодот за чистење може да биде трка во маскирање. „Откажи што е во тек, па стартувај“ изгледа како хигиена. Со две повикувачи, секој го поништува другиот.
  • Пуштете ја базата да арбитрира. Читање, па пишување, остава простор за друго барање. Една условна наредба не остава.
  • Секое заклучување треба рок врзан за живост. Без него, паѓањето се претвора во заглавена апликација.
  • Пораките за грешка се упатства. „Тоа име е зафатено“ им кажуваше на луѓето да направат погрешно. Точната порака беше поедноставна и вистинита.

Повеќе за објавувањето во документацијата: how to publish. И сродна поправка: вашата објавена апликација останува достапна додека ја повторно објавувате.

Mythex · Pricing · Градете што било со AI · Шаблони за веб-страници и апликации · Mythex во споредба · Речник за градење апликации со AI · Бесплатни алатки за градење апликации со AI · 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 日本語 ქართული Қазақ тілі ಕನ್ನಡ 한국어 Lietuvių 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 简体中文 繁體中文(香港) 繁體中文(台灣)