ബ്ലോഗ്

Publish രണ്ടുതവണ അമർത്തിയാലും ഇപ്പോൾ ഒരു തവണ മാത്രം പ്രസിദ്ധീകരിക്കുന്നു

ഒരേ ആപ്പിനുള്ള മൂന്ന് publish അഭ്യർത്ഥനകൾ ഞങ്ങളുടെ API-യിൽ 84 മില്ലിസെക്കൻഡ് ഇടവിട്ട് എത്തി, ഓരോന്നും ആ ആപ്പിന്റെ പൂർണ്ണ deploy ആരംഭിച്ചു. അവ ഒരേ hosting-ലേക്ക് മത്സരിച്ചെത്തി, തുടർന്നുണ്ടായ റിലീസുകളിൽ പലതും മറ്റൊന്ന് നേരത്തെ എത്തിയതിനാൽ പരാജയപ്പെട്ടു, ദൃശ്യമായ ഒരേയൊരു അടയാളം "release failed" ഇമെയിൽ മാത്രമായിരുന്നു — ആപ്പ് ഒടുവിൽ ശരിയായിരുന്നു. ഇപ്പോൾ ഒരേ ആപ്പിന് പ്രവർത്തിക്കുന്ന മറ്റൊരു publish ഉള്ളപ്പോൾ എത്തുന്ന publish രണ്ടാമത് ഒരു build ആരംഭിക്കുന്നില്ല. ഏത് അഭ്യർത്ഥന ജയിക്കണമെന്ന് ഡാറ്റാബേസ് തീരുമാനിക്കുന്നു, മറ്റുള്ളവരോട് സത്യം പറയുന്നു: ഒരു publish ഇതിനകം നടക്കുന്നുണ്ട്.

എന്താണ് സംഭവിച്ചത്

നിങ്ങൾ Mythex-ൽ ഒരു ആപ്പ് publish ചെയ്യുമ്പോൾ, API ആ ആപ്പിനായി ഒരു deployment രേഖപ്പെടുത്തുകയും build-ഉം release-ഉം നടത്താൻ ഞങ്ങളുടെ orchestrator-നോട് ആവശ്യപ്പെടുകയും ചെയ്യുന്നു — build-കൾ പ്രവർത്തിപ്പിക്കുന്ന സേവനം. Publish Button-ൽ നിന്നോ, മറ്റൊരു ബ്രൗസർ ടാബിൽ നിന്നോ, നിങ്ങൾ ആവശ്യപ്പെടുമ്പോൾ agent-ൽ നിന്നോ ആരംഭിക്കാം. ഇരട്ട ക്ലിക്ക്, രണ്ട് ടാബുകൾ, അല്ലെങ്കിൽ രണ്ടുതവണ എത്തുന്ന ഒരു agent അഭ്യർത്ഥന എന്നിവയെല്ലാം ഏതാണ്ട് ഒരേ നിമിഷത്തിൽ ഒരേ ആപ്പിന് ഒന്നിലധികം publish-കൾ ഉണ്ടാക്കാം.

ഈ സാഹചര്യത്തിൽ, മൂന്ന് എണ്ണം 84 ms-നുള്ളിൽ എത്തി. ഓരോന്നും പൂർണ്ണ deploy പ്രവർത്തിപ്പിച്ചു. Hosting platform-ൽ, ഒരേ ആപ്പിന്റെ റിലീസുകൾ ഒരേ സെക്കൻഡിൽ സൃഷ്ടിക്കപ്പെട്ടു, അവയിൽ മൂന്നെണ്ണം പരാജയപ്പെട്ടു, കാരണം മറ്റുള്ളവ ഇതിനകം പുരോഗമിക്കുകയായിരുന്നു. ഒരു പിന്നീടുള്ള റിലീസ് കുടുങ്ങി, പിന്നീട് ആപ്പ് പ്രവർത്തിച്ചു.

അതാണ് ഇത് കണ്ടെത്താൻ എളുപ്പമല്ലാതാക്കിയത്. ഉപയോക്താവ് കണ്ടത് ഒരു പ്രവർത്തിക്കുന്ന ആപ്പ് മാത്രം. പരാജയങ്ങൾ release-failure ഇമെയിലുകളിൽ മാത്രമാണ് കാണിച്ചത്.

ഒന്നും തടയാതിരുന്നത് എന്തുകൊണ്ട്

Publish കോഡിൽ ഒരു പ്രോജക്റ്റിന്റെ പുരോഗമിക്കുന്ന deploy-കൾ നോക്കുന്ന ഒരു ഘട്ടമുണ്ടായിരുന്നു. എന്നാൽ അത് ചെയ്തത്, ആരംഭിക്കുന്നതിന് മുമ്പ് പുരോഗമിക്കുന്ന ഓരോ deploy-യും പരാജയപ്പെട്ടതായി അടയാളപ്പെടുത്തുക എന്നതായിരുന്നു — "a new publish superseded it" എന്ന്. ക്രാഷ് ആയ ഒരു പ്രക്രിയ അവശേഷിപ്പിച്ച build-കൾ വൃത്തിയാക്കാനായിരുന്നു ഉദ്ദേശ്യം.

പ്രായോഗികമായി, build നടക്കുന്നതിനിടയിൽ എത്തുന്ന രണ്ടാമത്തെ publish ആദ്യത്തേതിനെ മരിച്ചതായി പ്രഖ്യാപിക്കുകയും സ്വന്തം build ആരംഭിക്കുകയും ചെയ്തു. രണ്ടും ഒരേ ആപ്പിനെതിരെ പൂർത്തിയാക്കി. ഒരു ലോക്കും ഉണ്ടായിരുന്നില്ല; മത്സരത്തിന് വഴി തുറന്നുകൊടുക്കുന്ന, സജീവമായി മായ്ക്കുന്ന ഒരു ഘട്ടം മാത്രമായിരുന്നു.

ഒരു ആപ്പിന്റെ ആദ്യ publish-ന് രണ്ടാമതൊരു, വിചിത്രമായ ലക്ഷണവും ഉണ്ടായിരുന്നു. Reuse ചെയ്യാൻ ഇതുവരെ deployment രേഖയില്ലാത്തതിനാൽ, ഒരേസമയത്തുള്ള രണ്ട് ആദ്യ publish-കളും ഒന്ന് insert ചെയ്യാൻ ശ്രമിച്ചു. ഡാറ്റാബേസിൽ ആപ്പിന്റെ link name-ൽ (അതിന്റെ slug, your-app.mythex.ai-ലെ your-app പോലെ) ഒരു unique index ഉണ്ട്, അതിനാൽ രണ്ടാമത്തെ insert പരാജയപ്പെട്ടു. API അതിനെ "ആ link name ഉപയോഗത്തിലാണ്" എന്ന് മാറ്റി — ആ നിമിഷത്തിൽ ആ പേരിൽ വിജയകരമായി publish ചെയ്തുകൊണ്ടിരുന്ന ഒരു ആപ്പിന്റെ പേര് മാറ്റാൻ ഉപയോക്താവിനോട് ഉപദേശിച്ചു.

പരിഹാരം: ക്ലെയിം തന്നെ ലോക്ക്

Deployment രേഖ ക്ലെയിം ചെയ്യുന്നത് ഇപ്പോൾ ഒറ്റ conditional database update ആണ്: ഈ വരി എടുത്ത്, ആരും publish ചെയ്യുന്നില്ലെങ്കിൽ മാത്രം building എന്ന് അടയാളപ്പെടുത്തുക. ഇത് ഒറ്റ statement ആയതിനാൽ, ഒരേ മില്ലിസെക്കൻഡിൽ എത്തുന്ന അഭ്യർത്ഥനകളെ ഡാറ്റാബേസ് തീർപ്പാക്കുന്നു. കൃത്യം ഒരാൾ മാത്രം വരി മാറ്റുന്നു. മറ്റുള്ളവർ പൂജ്യം വരികൾ മാറിയതായി കാണുന്നു, നിൽക്കുന്നു, ഒരിക്കലും orchestrator-ൽ എത്തുന്നില്ല.

ലോക്കിന്റെ ഉടമ മരിച്ചാൽ പുറത്തുകടക്കാനുള്ള വഴിയും വേണം. Publish മധ്യത്തിൽ API റീസ്റ്റാർട്ട് ആയാൽ, വരി എന്നെന്നേക്കുമായി "building" ആയി നിൽക്കും, ആപ്പ് ഒരിക്കലും വീണ്ടും publish ചെയ്യാനാകില്ല. അതിനാൽ ഹാർട്ട്ബീറ്റ് അയയ്ക്കാത്ത വരിയെ — പ്രവർത്തിക്കുന്ന publish ഓരോ 30 സെക്കൻഡിലും വരി അപ്ഡേറ്റ് ചെയ്യുന്നു, അഞ്ച് മിനിറ്റ് നിശബ്ദത മരിച്ചതായി കണക്കാക്കുന്നു — വീണ്ടും ക്ലെയിം ചെയ്യാം. ആ പരിധി ഹാർട്ട്ബീറ്റിൽ നിന്നാണ് വരുന്നത്, build എത്ര സമയമെടുക്കുമെന്ന ഊഹത്തിൽ നിന്നല്ല. ഉപയോക്താവിന്റെ സ്വന്തം Dockerfile build ചെയ്യുന്നത് ന്യായമായും ദീർഘനേരം എടുക്കാം, ഇപ്പോഴും ഹാർട്ട്ബീറ്റ് ചെയ്യുന്ന സാവധാനമുള്ള build അതിന്റെ ക്ലെയിം നിലനിർത്തുന്നു.

ഒരു publish ആരംഭിക്കുന്നതിന് മുമ്പ് പുരോഗമിക്കുന്ന എല്ലാ deploy-കളും പരാജയപ്പെടുത്തിയിരുന്ന ഘട്ടം ഇപ്പോൾ പ്രവർത്തിക്കുന്നില്ല. മരിച്ച ഒരു പ്രക്രിയ ഉപേക്ഷിച്ച വരികൾ മാത്രമേ മായ്ക്കപ്പെടുന്നുള്ളൂ.

തോറ്റ അഭ്യർത്ഥനയോട് സത്യം പറയുക

തോൽക്കുന്ന അഭ്യർത്ഥനയ്ക്ക് ഇപ്പോൾ വ്യക്തമായ ഉത്തരം ലഭിക്കുന്നു: publish_in_progress, ഒപ്പം പ്രവർത്തിക്കുന്ന deployment-ന്റെ ID-യും. Publish ആരംഭിക്കാവുന്ന ഓരോ സ്ഥലവും അത് കൈകാര്യം ചെയ്യുന്നു:

  • വർക്ക്‌സ്‌പേസ് ഇതിനകം പ്രവർത്തിക്കുന്ന build-നെ പിന്തുടരുന്നു, അതിന് മുകളിൽ ഒരു പിശക് കാണിക്കുന്നതിന് പകരം.
  • Agent-നോട് ഈ ആപ്പിന്റെ ഒരു publish ഇതിനകം പ്രവർത്തിക്കുന്നുണ്ടെന്നും അതിനായി കാത്തിരിക്കാനും പറയുന്നു, ഒരു പരാജയം സംഭവിച്ചതായി പറയുന്നതിന് പകരം — അതിനാൽ മുമ്പ് അത് Dockerfile "ശരിയാക്കാൻ" പോയി വീണ്ടും ശ്രമിക്കാൻ പ്രേരിപ്പിച്ചിരുന്നു.
  • ആദ്യ publish-ലെ link name collision പരിശോധിക്കുന്നു: പേര് കൈവശം വെച്ചിരിക്കുന്ന വരി ഈ പ്രോജക്റ്റിന്റെ സ്വന്തം പ്രവർത്തിക്കുന്ന publish ആണെങ്കിൽ, ഉത്തരം "already publishing" ആണ്, "that name is taken" അല്ല. മറ്റൊരു പ്രോജക്റ്റുമായുള്ള യഥാർത്ഥ collision ഇപ്പോഴും പേര് മാറ്റാനുള്ള സന്ദേശം ലഭിക്കുന്നു.

ഞങ്ങൾ എങ്ങനെ പരിശോധിച്ചു

ഒരു യഥാർത്ഥ ഡാറ്റാബേസിനും ഒരു stub orchestrator-നും എതിരെ ഒരേ ആപ്പിന്റെ മൂന്ന് publish-കൾ ഒരേ സമയം പ്രവർത്തിപ്പിച്ച്, orchestrator എത്ര deploy-കൾ ആവശ്യപ്പെടുന്നു എന്ന് എണ്ണുന്ന ഒരു reproduction script എഴുതി. അത് ആദ്യ publish പ്രവർത്തിക്കുന്ന ആപ്പിന്റെ republish-ഉം ഉൾക്കൊള്ളുന്നു. പരിഹാരത്തിന് മുമ്പ് അത് രണ്ട് deploy എണ്ണി. ശേഷം ഒന്ന്.

Script രക്ഷപ്പെടാനുള്ള വഴിയും ഉൾക്കൊള്ളുന്നു: ആപ്പിന്റെ വരി പത്ത് മിനിറ്റ് ഹാർട്ട്ബീറ്റ് ഇല്ലാതെ building എന്ന് അടയാളപ്പെടുത്തുന്നു, വീണ്ടും publish ചെയ്യുന്നു, പുതിയ publish വരി ക്ലെയിം ചെയ്ത് പ്രവർത്തിക്കുന്നു എന്ന് പരിശോധിക്കുന്നു.

Unit tests ലോക്കിനെ അത് ചെയ്യേണ്ട രണ്ട് കാര്യങ്ങളിൽ ഉറപ്പിക്കുന്നു: ഒരേസമയത്തുള്ള മൂന്ന് republish-കളിൽ കൃത്യം ഒന്ന് കടന്നുപോകുന്നു, മറ്റ് രണ്ടിനോട് ഒരു publish പ്രവർത്തിക്കുന്നു എന്ന് പറയുന്നു; ഉടമ മരിച്ച ഒരു build ക്ലെയിം ചെയ്യാം. മറ്റൊരു ടെസ്റ്റ് പരിശോധിക്കുന്നത്, പുതിയ ശ്രമം മുമ്പത്തെ ശ്രമത്തിന്റെ പിശക് സന്ദേശം കൊണ്ടുപോകുന്നില്ല എന്നാണ്.

ഞങ്ങൾ ഇതിൽ നിന്ന് പഠിച്ചത്

  • Cleanup കോഡ് മറഞ്ഞിരിക്കുന്ന ഒരു race ആകാം. "പുരോഗമിക്കുന്നതെല്ലാം പരാജയപ്പെടുത്തുക, എന്നിട്ട് തുടങ്ങുക" ശുചിത്വം പോലെ തോന്നാം. രണ്ട് caller-മാർ ഉണ്ടെങ്കിൽ, ഓരോരുത്തരും മറ്റൊരാളെ റദ്ദാക്കുകയാണ്.
  • ഡാറ്റാബേസിനെ തീർപ്പാക്കാൻ അനുവദിക്കുക. ഒരു read തുടർന്ന് ഒരു write മറ്റൊരു അഭ്യർത്ഥനയ്ക്ക് ഇടം നൽകുന്നു. ഒറ്റ conditional update അങ്ങനെ ചെയ്യുന്നില്ല.
  • ഓരോ ലോക്കിനും ജീവനുമായി ബന്ധിപ്പിച്ച ഒരു കാലഹരണം വേണം. ഇല്ലെങ്കിൽ ഒരു ക്രാഷ് കുടുങ്ങിയ ആപ്പായി മാറുന്നു.
  • പിശക് സന്ദേശങ്ങൾ നിർദ്ദേശങ്ങളാണ്. "ആ പേര് ഉപയോഗത്തിലാണ്" തെറ്റായ കാര്യം ചെയ്യാൻ ആളുകളോട് പറഞ്ഞു. ശരിയായ സന്ദേശം ലളിതവും സത്യവുമായിരുന്നു.

Publishing-നെക്കുറിച്ച് കൂടുതൽ ഡോക്സിൽ: how to publish. ഒരു അനുബന്ധ പരിഹാരം: നിങ്ങളുടെ publish ചെയ്ത ആപ്പ് republish ചെയ്യുമ്പോഴും പ്രവർത്തിക്കുന്നു.

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 简体中文 繁體中文(香港) 繁體中文(台灣)