દરેક વ્યક્તિ રિયલ-ટાઇમ અપડેટ્સ ઈચ્છે છે જ્યાં સુધી તેમને એ સમજાઈ ન જાય કે "ઝડપી" અને "સાચું" એ એક સમાન નથી. ડિસ્ટ્રિબ્યુટેડ સિસ્ટમમાં, ઇવેન્ટ્સ પ્રકાશની ગતિએ મુસાફરી કરી શકે છે અને તેમ છતાં ખોટા ક્રમમાં આવી શકે છે. WebSockets ડ્રોપ થાય છે અને ફરીથી કનેક્ટ થાય છે. Message brokers પેકેટ્સ ફરીથી મોકલે છે. Background workers ટાઈમઆઉટ કેન્સલેશન સામે સ્પર્ધા કરે છે. પરિણામ? ક્લાયન્ટ ઇવેન્ટ 42 જોઈ શકે છે, પછી ઇવેન્ટ 40, અને પછી એક સ્નેપશોટ જે દાવો કરે છે કે સિસ્ટમ પહેલેથી જ ઇવેન્ટ 45 પર છે. જો તમે લાંબા સમય સુધી ચાલતા એજન્ટ વર્કફ્લો બનાવી રહ્યા હોવ, તો તે અરાજકતા કોઈ અપવાદ (edge case) નથી. તે પાયાની સમસ્યા છે. ડિલિવરીમાંથી મિલીસેકન્ડ ઘટાડવાની ચિંતા કરતા પહેલા તમારી ઇવેન્ટ્સનો ક્રમ સુધારો.
"રિયલ-ટાઇમ" ની અસ્તવ્યસ્ત વાસ્તવિકતા
રિયલ-ટાઇમ એ ટ્રાન્સપોર્ટ પ્રોપર્ટી છે. તે પેકેટ વાયર પર કેટલી ઝડપથી મુસાફરી કરે છે તેનું વર્ણન કરે છે, તે નહીં કે તે જે વાર્તા કહે છે તે તર્કસંગત છે કે નહીં. લાંબા સમય સુધી ચાલતા કાર્યો દરેક અસંગતતાને વધારી દે છે કારણ કે તેઓ સમયના લાંબા ગાળા સુધી ફેલાયેલા હોય છે. મોડેલ ટ્રેનિંગ જોબ, મલ્ટી-સ્ટેપ એપ્રુવલ ફ્લો, અથવા વિડિયો રેન્ડરિંગ પાઇપલાઇન મિનિટો કે કલાકો દરમિયાન ડઝનબંધ ઇવેન્ટ્સ બહાર પાડી શકે છે. તે સમયગાળા દરમિયાન, કંઈ પણ ખોટું થઈ શકે છે.
એક બ્રોકર મેસેજ ફરીથી મોકલવાનો પ્રયાસ કરી શકે છે કારણ કે એક્નોલેજમેન્ટ (acknowledgement) ખોવાઈ ગયું હોય. લોડ બેલેન્સર બે ઇવેન્ટ્સને અલગ-અલગ નેટવર્ક પાથ પર મોકલી શકે છે, જેનાથી નવી ઇવેન્ટ પહેલા આવી શકે છે. ડેટાબેઝમાં લખ્યા પછી પણ સક્સેસ ઇવેન્ટ પબ્લિશ કરતા પહેલા વર્કર પ્રોસેસ બંધ થઈ શકે છે, અને પછી બીજો વર્કર તે કાર્ય ઉપાડીને તેની પોતાની પ્રગતિ જાહેર કરી શકે છે. જો તમારું ફ્રન્ટએન્ડ એવું માની લે કે લેટેસ્ટ મેસેજ એ સૌથી સાચો મેસેજ છે, તો તે એવી સ્થિતિ (state) દર્શાવશે જે ક્યારેય અસ્તિત્વમાં જ નહોતી. વપરાશકર્તાઓ "completed" બેજને ફરીથી "processing" માં બદલાતા જોઈ શકશે, અથવા તેનાથી પણ ખરાબ, કેન્સલ થયેલું કાર્ય અચાનક ફરીથી શરૂ થઈ જશે. ક્રમ વગરની ઝડપ એ માત્ર ઉચ્ચ ફ્રેમ રેટ પરની મૂંઝવણ છે.
સિક્વન્સ નંબર્સ એ સાચું ક્લોક છે
તેનો ઉકેલ પ્રોડ્યુસર દ્વારા જનરેટ કરવામાં આવેલા કડક, મોનોટોનિક (monotonic) સિક્વન્સ નંબર્સ છે. સ્ટેટ બદલતા દરેક ઓપરેશનને એક નંબર મળે છે જે કોઈપણ ગેપ અથવા રોલબેક વગર બરાબર એક વધે છે. તે નંબર ઇવેન્ટની સાથે જ તે જ ટ્રાન્ઝેક્શનમાં સેવ (persist) થવો જોઈએ. જો ડેટાબેઝ રો અપડેટ થાય પરંતુ સિક્વન્સ કમિટ નિષ્ફળ જાય, તો તમારે બંનેને રોલબેક કરવા જોઈએ. આ લોજિકલ ટાઈમલાઇનને સ્ટેટ ચેન્જ સાથે એટમિક (atomic) રાખે છે.
ઇવેન્ટ આઈડી (Event IDs) હજુ પણ ઉપયોગી છે, પરંતુ તે અલગ સમસ્યાનો ઉકેલ આપે છે. ઇવેન્ટ આઈડી એક ચોક્કસ પેલોડને ઓળખે છે જેથી જ્યારે બ્રોકર એક જ મેસેજ બે વાર મોકલે ત્યારે તમે તેને ડુપ્લીકેટ થતો અટકાવી શકો. બીજી તરફ, સિક્વન્સ નંબર તમને જણાવે છે કે તે પેલોડ કોઝલ ચેઇનમાં (causal chain) ક્યાં આવે છે. તે ગેપ્સ અને ક્રમ (ordering) ને ખુલ્લો પાડે છે. ટાઈમસ્ટેમ્પ આ બંને કામ નથી કરી શકતું. ક્લોક ડ્રિફ્ટ થાય છે, NTP પાછળ જાય છે, અને વર્ચ્યુઅલ મશીનો અટકી જાય છે. ટાઈમસ્ટેમ્પનો ઉપયોગ ફક્ત ડિસ્પ્લે હેતુ માટે કરો, જેમ કે "3 મિનિટ પહેલા શરૂ થયું," અને બિઝનેસ લોજિક માટે સોર્ટિંગ કી તરીકે ક્યારેય તેનો ઉપયોગ કરશો નહીં.
ક્લાયન્ટે સ્ટ્રીમને કેવી રીતે હેન્ડલ કરવી જોઈએ
એકવાર પ્રોડ્યુસર મોનોટોનિક સિક્વન્સની ખાતરી આપે, પછી કન્ઝ્યુમર માટે સરળ અને કડક નિયમો બની જાય છે. જો ઇનબાઉન્ડ સિક્વન્સ નંબર છેલ્લે લાગુ કરાયેલ નંબર કરતા ઓછો અથવા તેના જેટલો હોય, તો તેને ડ્રોપ કરી દો. તે કાં તો ડુપ્લીકેટ છે અથવા જૂનો છે. જો સિક્વન્સ છેલ્લે લાગુ કરાયેલ નંબર કરતા બરાબર એક વધારે હોય, તો તેને તરત જ લાગુ કરો. તે 'હેપ્પી પાથ' છે. જો સિક્વન્સ આગળ કૂદી જાય, ધારો કે તમે 12 ની અપેક્ષા રાખી હતી પરંતુ 15 મળ્યા, તો કંઈક ખૂટે છે. નવા ઇવેન્ટને બફર કરો અને આગામી અપેક્ષિત સિક્વન્સથી રીપ્લે માટે સર્વરને પૂછો. અનુમાન ન લગાવો. ગેપ મહત્વનો નથી તેવી આશામાં આગળ ન કૂદો.
ટર્મિનલ સ્ટેટ્સને અફર (irrevocable) તરીકે ગણવા જોઈએ. એકવાર કાર્ય પૂર્ણ (completed), નિષ્ફળ (failed), અથવા રદ (cancelled) તરીકે ચિહ્નિત થઈ જાય પછી, ક્લાયન્ટે તે ઓપરેશન માટેના કોઈપણ પછીના સ્ટેટ ચેન્જને નકારવા જોઈએ. આ સાંભળવામાં સ્પષ્ટ લાગે છે જ્યાં સુધી તમે...
