Publish બે વાર દબાવવાથી હવે એક જ વાર પબ્લિશ થાય છે
એક જ એપ માટે ત્રણ પબ્લિશ રિક્વેસ્ટ 84 મિલિસેકન્ડના અંતરે અમારા API સુધી પહોંચી, અને દરેકે તે એપનું આખું ડિપ્લોય શરૂ કર્યું. તેઓ એક જ હોસ્ટિંગ પર એકબીજા સાથે રેસ કરતા, પરિણામે ઘણી રિલીઝ નિષ્ફળ ગઈ કારણ કે બીજી કોઈ પહેલાં પહોંચી ગઈ હતી, અને દેખાતો એકમાત્ર સંકેત "release failed" ઈમેઇલ હતો. એપ પોતે અંતે બરાબર હતી. હવે એક જ એપ માટે ચાલતા પબ્લિશ દરમિયાન આવતું બીજું પબ્લિશ બીજો બિલ્ડ શરૂ કરતું નથી. ડેટાબેઝ નક્કી કરે છે કે કઈ રિક્વેસ્ટ જીતે છે, અને બાકીનાને સાચું કહેવામાં આવે છે: પબ્લિશ પહેલેથી ચાલુ છે.
શું થયું
જ્યારે તમે Mythex પર એપ પબ્લિશ કરો છો, ત્યારે API તે માટે ડિપ્લોયમેન્ટ રેકોર્ડ બનાવે છે અને અમારા ઓર્કેસ્ટ્રેટરને, એટલે કે બિલ્ડ ચલાવતી સેવાને, તેને બિલ્ડ અને રિલીઝ કરવા કહે છે. પબ્લિશ Publish બટનથી, બીજા બ્રાઉઝર ટેબથી, અથવા તમે માગો ત્યારે એજન્ટથી શરૂ થઈ શકે છે. ડબલ ક્લિક, બે ટેબ, અથવા બે વાર આવતી એજન્ટ રિક્વેસ્ટ, આ બધાં લગભગ એક જ ક્ષણે એક જ એપ માટે એક કરતાં વધુ પબ્લિશ બનાવી શકે છે.
આ કિસ્સામાં ત્રણ 84 ms ની અંદર આવ્યા. દરેકે આખું ડિપ્લોય ચલાવ્યું. હોસ્ટિંગ પ્લેટફોર્મ પર, એક જ એપ માટેની રિલીઝ એક જ સેકન્ડમાં બનાવાઈ, અને તેમાંની ત્રણ નિષ્ફળ ગઈ કારણ કે બીજી પહેલેથી ચાલુ હતી. પછી એક રિલીઝ ટકી ગઈ, અને તે પછી એપ કામ કરતી હતી.
એ જ વાત તેને ચૂકી જવામાં સરળ બનાવતી. યુઝરે એક કામ કરતી એપ જોઈ. નિષ્ફળતા માત્ર release-failure ઈમેઇલમાં દેખાઈ.
કશું કેમ રોકતું નહોતું
પબ્લિશ કોડમાં એક સ્ટેપ હતો જે પ્રોજેક્ટના ચાલુ ડિપ્લોય જોતો. પણ તે શું કરતો: શરૂ થતાં પહેલાં દરેક ચાલુ ડિપ્લોયને "superseded by a new publish" કહીને failed માર્ક કરી દેતો. તેનો હેતુ એવા બિલ્ડ સાફ કરવાનો હતો જે ક્રેશ થયેલી પ્રોસેસ પાછળ છોડી ગઈ હોય.
વ્યવહારમાં, બિલ્ડ વચ્ચે આવતું બીજું પબ્લિશ પહેલાંને મૃત જાહેર કરીને પોતાનું શરૂ કરી દેતું. બંને એક જ એપ સામે પૂરાં થતાં. ત્યાં કોઈ લોક નહોતો; ત્યાં એક એવું સ્ટેપ હતું જે સક્રિય રીતે રેસ માટે રસ્તો સાફ કરતું.
એપના પહેલા પબ્લિશ માટે બીજું, વધુ વિચિત્ર લક્ષણ હતું. હજી કોઈ ડિપ્લોયમેન્ટ રેકોર્ડ ફરી વાપરવા માટે ન હોવાથી, બે એક સાથેના પહેલા પબ્લિશ બંને એક જ રેકોર્ડ insert કરવાની કોશિશ કરતા. ડેટાબેઝમાં એપના લિંક નામ (તેનું slug, જેમ કે your-app.mythex.ai માં your-app) પર unique index છે, એટલે બીજું insert નિષ્ફળ જતું. API તેને "that link name is taken" માં ફેરવતું, અને યુઝરને એ એપનું નામ બદલવાનું કહેતું, જે તે જ ક્ષણે તે નામ હેઠળ સફળતાપૂર્વક પબ્લિશ થઈ રહી હતી.
ઉકેલ: claim એ જ લોક છે
ડિપ્લોયમેન્ટ રેકોર્ડનો claim હવે એક જ શરતી ડેટાબેઝ અપડેટ છે: આ રો લો અને તેને building માર્ક કરો માત્ર જો કોઈ તેને પબ્લિશ ન કરતું હોય. તે એક જ સ્ટેટમેન્ટ હોવાથી, ડેટાબેઝ એક જ મિલિસેકન્ડમાં આવતી રિક્વેસ્ટ્સનો નિર્ણય કરે છે. તેમાંથી એક જ રો બદલે છે. બાકીના જુએ છે કે શૂન્ય રો બદલાઈ, અટકી જાય છે, અને ઓર્કેસ્ટ્રેટર સુધી પહોંચતા નથી.
લોકને તેના ધારકના મૃત્યુ વખતે બહાર નીકળવાનો રસ્તો પણ જોઈએ. જો પબ્લિશ દરમિયાન API ફરી શરૂ થાય, તો રો હંમેશ માટે "building" રહેત અને એપ અપબ્લિશેબલ બની જાત. તેથી જે રો ના માલિકે હાર્ટબીટ મોકલવાનું બંધ કર્યું હોય તે ફરી claim થઈ શકે છે. ચાલતું પબ્લિશ દર 30 સેકન્ડે રો અપડેટ કરે છે, અને પાંચ મિનિટ શાંતિ મૃત ગણાય છે. આ થ્રેશોલ્ડ હાર્ટબીટ પરથી આવે છે, બિલ્ડ કેટલો સમય લે તેના અંદાજ પરથી નહીં. યુઝરનું પોતાનું Dockerfile બિલ્ડ કરવામાં કાયદેસર રીતે લાંબો સમય લાગી શકે છે, અને હાર્ટબીટ કરતો ધીમો બિલ્ડ પોતાનો claim જાળવી રાખે છે.
જે સ્ટેપ પબ્લિશ પહેલાં ચાલુ ડિપ્લોયને નિષ્ફળ કરતો હતો તે હવે ચાલતો નથી. માત્ર મૃત પ્રોસેસે પાછળ છોડેલી રો સાફ થાય છે.
હારનારને સાચું કહેવું
જે રિક્વેસ્ટ હારે છે તેને હવે સ્પષ્ટ જવાબ મળે છે: publish_in_progress, ચાલતા ડિપ્લોયના ID સાથે. પબ્લિશ શરૂ કરી શકે તેવી દરેક જગ્યા તેને સંભાળે છે:
- વર્કસ્પેસ ભૂલ બતાવવાને બદલે પહેલેથી ચાલતા બિલ્ડને અનુસરે છે.
- એજન્ટને કહેવામાં આવે છે કે આ એપનું પબ્લિશ પહેલેથી ચાલુ છે અને તેની રાહ જુઓ, એવું નહીં કે કંઈ નિષ્ફળ ગયું છે. પહેલાં આ તેને Dockerfile "ઠીક" કરવા અને ફરી પ્રયાસ કરવા મોકલી શકતું.
- પહેલા પબ્લિશની લિંક નામ અથડામણ તપાસાય છે: જો નામ ધરાવતી રો આ પ્રોજેક્ટનું પોતાનું ચાલતું પબ્લિશ હોય, તો જવાબ "already publishing" છે, "that name is taken" નહીં. બીજા પ્રોજેક્ટ સાથે સાચી અથડામણ હજી નામ બદલવાનો સંદેશ મેળવે છે.
અમે તેને કેવી રીતે ચકાસ્યું
અમે એક રિપ્રોડક્શન સ્ક્રિપ્ટ લખી જે એક વાસ્તવિક ડેટાબેઝ અને એક સ્ટબ ઓર્કેસ્ટ્રેટર સામે એક જ એપના ત્રણ પબ્લિશ એક સાથે ચલાવે છે, અને ગણે છે કે ઓર્કેસ્ટ્રેટરને કેટલા ડિપ્લોય માટે પૂછવામાં આવ્યું. તે પહેલું પબ્લિશ અને લાઇવ એપનું રિ-પબ્લિશ બંને આવરી લે છે. ફિક્સ પહેલાં, તેણે બે ડિપ્લોય ગણ્યા. પછી, એક.
સ્ક્રિપ્ટ બચાવના રસ્તાને પણ આવરી લે છે: તે એપની રો દસ મિનિટ સુધી હાર્ટબીટ વગર building તરીકે માર્ક કરે છે, ફરી પબ્લિશ કરે છે, અને તપાસે છે કે નવું પબ્લિશ રોને claim કરીને ચાલે છે.
યુનિટ ટેસ્ટ લોકને તે બે કામ સુધી સીમિત રાખે છે જે લોકે કરવાં જ જોઈએ: એક સાથેના ત્રણ રી-પબ્લિશમાંથી બરાબર એક આગળ જાય છે અને બાકીના બે કહેવાય છે કે પબ્લિશ ચાલુ છે; અને જેના માલિકનું મૃત્યુ થયું હોય તે બિલ્ડ claim કરી શકાય છે. બીજી ટેસ્ટ તપાસે છે કે નવો પ્રયાસ પાછલા પ્રયાસનો એરર સંદેશ આગળ લઈ જતો નથી.
અમે શું શીખ્યા
- ક્લીનઅપ કોડ છુપાયેલી રેસ બની શકે. "ચાલતા બધાને નિષ્ફળ કરો, પછી શરૂ કરો" સ્વચ્છતા જેવું વાંચાય છે. બે કૉલર હોય ત્યારે, દરેક બીજાને રદ કરે છે.
- ડેટાબેઝને નિર્ણય કરવા દો. પહેલા વાંચન અને પછી લખાણ વચ્ચે બીજી રિક્વેસ્ટ માટે ગેપ રહે છે. એક જ શરતી અપડેટ આવો ગેપ છોડતું નથી.
- દરેક લોકને લાઇવનેસ સાથે જોડાયેલી એક્સપાયરી જોઈએ. તે વિના, ક્રેશ અટકેલી એપમાં ફેરવાય છે.
- એરર સંદેશ સૂચનાઓ છે. "That name is taken" લોકોને ખોટું કરવા કહેતું હતું. સાચો સંદેશ સરળ અને સત્ય હતો.
docs માં પબ્લિશિંગ વિશે વધુ: how to publish. અને સંબંધિત ફિક્સ: તમે પબ્લિશ કરેલી એપ ફરી પબ્લિશ કરતી વખતે પણ ચાલુ રહે છે.