Publish ကို နှစ်ခါနှိပ်ရင် ယခု တစ်ခါပဲ Publish လုပ်ပါတယ်
အက်ပ်တစ်ခုအတွက် publish request သုံးခုဟာ ကျွန်တော်တို့ API ဆီ 84 မီလီစက္ကန့် ခြားပြီး ရောက်လာပြီး၊ တစ်ခုစီက အဲဒီအက်ပ်အတွက် deploy အပြည့် စတင်ခဲ့ပါတယ်။ အဲဒီတွေက တူညီတဲ့ hosting ပေါ်မှာ အပြိုင်ပြေးခဲ့ပြီး release အချို့ဟာ တခြားတစ်ခုက ရောက်သွားလို့ မအောင်မြင်ခဲ့ပါတယ်၊ မြင်ရတဲ့ တစ်ခုတည်းသော လက္ခဏာက "release failed" အီးမေးလ် ဖြစ်ပြီး အက်ပ်ကိုယ်တိုင်က နောက်ဆုံး အဆင်ပြေခဲ့ပါတယ်။ ယခု အက်ပ်တစ်ခုအတွက် လုပ်ဆောင်နေစဉ် တစ်ခု ရောက်လာတဲ့ publish က build ဒုတိယ မစတော့ပါ။ database က ဘယ် request အနိုင်ရလဲ ဆုံးဖြတ်ပြီး၊ တခြားတွေကို အမှန်ကို ပြောပါတယ်– publish တစ်ခု ပြီးမြောက်နေပြီ။
ဘာဖြစ်ခဲ့လဲ
Mythex မှာ အက်ပ်ကို publish လုပ်တဲ့အခါ API က deployment record တစ်ခု မှတ်ပြီး orchestrator ကို– build တွေ လုပ်တဲ့ ဝန်ဆောင်မှု– build လုပ်ပြီး release လုပ်ဖို့ တောင်းပါတယ်။ Publish ကို Publish ခလုတ်၊ တခြား browser tab၊ ဒါမှမဟုတ် သင်တောင်းတဲ့အခါ agent ကနေ စတင်နိုင်ပါတယ်။ နှစ်ကြိမ် ကလစ်၊ tab နှစ်ခု၊ ဒါမှမဟုတ် နှစ်ခါရောက်တဲ့ agent request တွေဟာ အက်ပ်တစ်ခုအတွက် publish တစ်ခုထက်ပို ဖြစ်စေနိုင်ပြီး နီးနီးပင် တစ်ပြိုင်တည်း ဖြစ်ပါတယ်။
ဒီဖြစ်ရပ်မှာ သုံးခု 84 ms အတွင်း ရောက်ခဲ့ပါတယ်။ တစ်ခုစီက deploy အပြည့် run ခဲ့ပါတယ်။ hosting platform မှာ အက်ပ်တစ်ခုအတွက် release တွေက တစ်စက္ကန့်အတွင်းမှာ ဖန်တီးခဲ့ပြီး၊ သုံးခုက တခြားတွေ လုပ်နေဆဲ ဖြစ်လို့ မအောင်မြင်ခဲ့ပါတယ်။ နောက်ဆုံး release တစ်ခု ကပ်သွားပြီး အက်ပ်က နောက်ပိုင်း အလုပ်လုပ်ခဲ့ပါတယ်။
ဒါက လွယ်လွယ်နဲ့ သတိမထားမိအောင် ဖြစ်စေခဲ့ပါတယ်။ အသုံးပြုသူက အလုပ်လုပ်တဲ့ အက်ပ်တစ်ခုတည်း မြင်ခဲ့ပါတယ်။ ပျက်ကွက်မှုတွေက release failure အီးမေးလ်တွေမှာသာ ပေါ်ခဲ့ပါတယ်။
ဘာကြောင့် ဘာမှ မတားခဲ့လဲ
Publish code မှာ ပရောဂျက်အတွက် လုပ်ဆောင်နေတဲ့ deploy တွေကို ကြည့်တဲ့ အဆင့်တစ်ခု ရှိခဲ့ပါတယ်။ ဒါပေမယ့် ၎င်းက လုပ်ဆောင်နေတဲ့ deploy တိုင်းကို မစတင်ခင် failed လို့ မှတ်လိုက်ပါတယ်– "အသစ် publish က အစားထိုးထားသည်" ဆိုပြီး။ ၎င်းက ပျက်သွားတဲ့ process ကျန်ခဲ့တဲ့ build တွေကို ရှင်းဖို့ ရည်ရွယ်ပါတယ်။
လက်တွေ့မှာ build လုပ်နေစဉ် ဒုတိယ publish ရောက်လာရင် ပထမ တစ်ခုကို သေပြီလို့ ကြေညာပြီး ကိုယ်ပိုင် တစ်ခုကို စတင်ခဲ့ပါတယ်။ နှစ်ခုစလုံး အက်ပ်တူတစ်ခုကို ပြီးအောင် run ခဲ့ပါတယ်။ lock မရှိပါဘူး၊ race အတွက် လမ်းကို တက်ကြွစွာ ရှင်းပေးတဲ့ အဆင့်တစ်ခုသာ ရှိပါတယ်။
အက်ပ်ရဲ့ ပထမ publish အတွက် နောက်ထပ် ထူးခြားတဲ့ လက္ခဏာလည်း ရှိပါတယ်။ ပြန်သုံးဖို့ deployment record မရှိသေးတဲ့အခါ ပထမ publish နှစ်ခုက တစ်ခုကို insert လုပ်ဖို့ ကြိုးစားခဲ့ပါတယ်။ database မှာ အက်ပ်ရဲ့ link name (slug၊ ဥပမာ your-app.mythex.ai ထဲက your-app) အပေါ် unique index ရှိလို့ ဒုတိယ insert က မအောင်မြင်ခဲ့ပါဘူး။ API က အဲဒါကို "အဲဒီ link name ယူပြီးသား" လို့ ဘာသာပြန်ပြီး၊ အဲဒီအချိန်မှာ အဲဒီနာမည်နဲ့ အောင်မြင်စွာ publish ဖြစ်နေတဲ့ အက်ပ်ကို နာမည်ပြောင်းဖို့ အကြံပေးခဲ့ပါတယ်။
ပြင်ဆင်ချက်– လော့ခ်ဟာ claim ပါပဲ
deployment record ကို claim လုပ်တာက အခု တစ်ခုတည်းသော database conditional update ဖြစ်ပါတယ်– ဒီ row ကို ယူပြီး building အဖြစ် မှတ်ပါ အဲဒီ publish ဘယ်သူမှ မလုပ်နေမှသာ။ statement တစ်ခုတည်းဖြစ်လို့ database က အချိန်တူတူ ရောက်လာတဲ့ request တွေကို ဖြေရှင်းပေးပါတယ်။ တစ်ခုတည်းက row ပြောင်းပြီး၊ တခြားတွေက row ပြောင်းတာ သုညဆိုတာ တွေ့ပြီး ရပ်ကာ orchestrator ဆီ ဘယ်တော့မှ မရောက်ပါဘူး။
လော့ခ်ကို ကိုင်ထားသူ သေသွားရင် ထွက်ပေါက်လည်း လိုပါတယ်။ API က publish အလယ်မှာ ပြန်စရင် row က "building" အဖြစ် အမြဲ ကျန်ပြီး အက်ပ်က publish မလုပ်နိုင်တော့ပါ။ ဒါကြောင့် ပိုင်ရှင် heartbeat ပို့တာ ရပ်သွားတဲ့ row ကို ပြန် claim လုပ်လို့ရပါတယ်– run နေတဲ့ publish က row ကို စက္ကန့် 30 တိုင်း update လုပ်ပြီး၊ ငါးမိနစ် တိတ်ဆိတ်ရင် သေပြီလို့ ယူဆပါတယ်။ အဲဒီ threshold က heartbeat ကနေ လာတာ ဖြစ်ပြီး build ကြာချိန်ကို ခန့်မှန်းတာ မဟုတ်ပါ။ အသုံးပြုသူ၏ Dockerfile ကို တည်ဆောက်တာ ကြာနိုင်ပြီး heartbeat ရှိနေသေးတဲ့ နှေးတဲ့ build က claim ကို ဆက်ထားပါတယ်။
မပြီးသေးတဲ့ deployတွေကို မဖြစ်ခင် failed လုပ်တဲ့ အဆင့်ကို publish မစတင်ခင် ထပ် မလုပ်တော့ပါ။ process သေခဲ့တဲ့ နောက်ကျန် row တွေကိုသာ ရှင်းပါတယ်။
ရှုံးတဲ့သူကို အမှန်ကို ပြောခြင်း
ရှုံးတဲ့ request က ရှင်းလင်းတဲ့ အဖြေ ရပါတယ်– publish_in_progress နဲ့ အလုပ်လုပ်နေတဲ့ deployment ID ပါ။ publish စတင်နိုင်တဲ့ နေရာတိုင်း ဒါကို ကိုင်တွယ်ပါတယ်–
- Workspace က အမှားပြမပေးဘဲ၊ ပြီးသားလုပ်နေတဲ့ build ကို လိုက်ကြည့်ပါတယ်။
- Agent ကို ဒီအက်ပ် publish တစ်ခု ပြီးနေပြီဖြစ်လို့ စောင့်ဖို့ ပြောပါတယ်၊ တစ်ခုခု ပျက်ကွက်ပြီလို့ မပြောတော့ပါ– ယခင်က ၎င်းက Dockerfile ကို "ပြင်ဖို့" ပြီး ထပ်ကြိုးစားစေနိုင်ခဲ့ပါတယ်။
- ပထမ publish ရဲ့ link name ပဲ ဖြစ်တဲ့ collision ကို စစ်ပါတယ်– နာမည်ကို ကိုင်ထားတဲ့ row က ဒီပရောဂျက်ရဲ့ လုပ်ဆောင်နေတဲ့ publish ဖြစ်ရင် အဖြေက "ထုတ်ဝေနေပြီ" ဖြစ်ပြီး "နာမည်ယူပြီး" မဟုတ်ပါ။ တခြား ပရောဂျက်နဲ့ အမှန်တကယ် collision ဖြစ်ရင် နာမည်ပြောင်းဖို့ message ပေးပါတယ်။
ဘယ်လို စစ်ဆေးခဲ့လဲ
အက်ပ်တစ်ခုအတွက် publish သုံးခုကို အချိန်တူတူ run တဲ့ reproduction script တစ်ခု ရေးခဲ့ပါတယ်၊ အမှန်တကယ် database နဲ့ stub orchestrator ဆိုင်ရာ ဖြစ်ပြီး orchestrator က deploy ဘယ်နှစ်ခု တောင်းသလဲ ရေတွက်ပါတယ်။ ပထမ publish နဲ့ live အက်ပ် republish နှစ်ခုလုံး ပါဝင်ပါတယ်။ ပြင်ခင် deploy နှစ်ခု ရေတွက်ခဲ့ပြီး၊ ပြင်ပြီးနောက် တစ်ခု ဖြစ်ပါတယ်။
script က escape hatch ကိုလည်း ဖုံးလွှမ်းပါတယ်– အက်ပ်ရဲ့ row ကို heartbeat မရှိဘဲ မိနစ် ဆယ်ခု building အဖြစ် မှတ်ပြီး၊ ထပ် publish လုပ်ပြီး၊ အသစ် publish က row ကို claim ပြီး run တာ စစ်ပါတယ်။
unit test တွေက လော့ခ်က လုပ်ရမယ့် အရာ နှစ်ခုကို ကိုင်ထားပါတယ်– တပြိုင်နက် republish သုံးခုမှာ တစ်ခုတည်းသာ ဖြတ်သန်းပြီး၊ နောက်နှစ်ခုကို publish run နေတယ်လို့ ပြောတာ၊ နဲ့ owner သေသွားတဲ့ build ကို claim လုပ်လို့ရတာ။ အခြား test တစ်ခုက attempt အသစ်က ယခင် attempt ရဲ့ error message ကို မသယ်ဆောင်ကြောင်း စစ်ပါတယ်။
ဒီကနေ ရလာတာတွေ
- Cleanup code က ဝှက်ထားတဲ့ race ဖြစ်နိုင်ပါတယ်။ "လုပ်ဆောင်နေတာ အားလုံး fail လုပ်ပြီး ပြန်စ" ဆိုတာ သန့်ရှင်းရေးလို ဖတ်ရပေမယ့် ခေါ်သူနှစ်ယောက်ရှိရင် တစ်ယောက်က တစ်ယောက်ကို ပယ်ဖျက်နေတာ ဖြစ်ပါတယ်။
- Database ကို ဆုံးဖြတ်ခွင့် ပေးပါ။ ဖတ်ပြီး ရေးတာက တခြား request အတွက် ကွာဟချက် ရှိပါတယ်။ conditional update တစ်ခုတည်းက မရှိပါဘူး။
- လော့ခ်တိုင်းမှာ အသက်ရှင်မှုနဲ့ ချိတ်ထားတဲ့ သက်တမ်းကုန်ခြင်း လိုပါတယ်။ မရှိရင် crash က အက်ပ် ပိတ်ထားတဲ့ အခြေအနေ ဖြစ်သွားပါမယ်။
- Error message တွေက ညွှန်ကြားချက်တွေ ဖြစ်ပါတယ်။ "ထိုနာမည် ယူပြီးပြီ" က လူတွေကို မှားတဲ့ အရာ လုပ်ဖို့ ပြောခဲ့ပါတယ်။ မှန်တဲ့ message က ရိုးရှင်းပြီး မှန်ကန်ပါတယ်။
Docs မှာ publish အကြောင်း ပိုမိုရှိပါတယ်– how to publish။ ဆက်စပ် ပြင်ဆင်ချက်တစ်ခုကတော့ your published app stays up while you republish it ဖြစ်ပါတယ်။