എല്ലാവരും റിയൽ-ടൈം അപ്‌ഡേറ്റുകൾ ആഗ്രഹിക്കുന്നു, എന്നാൽ "വേഗത"യും "കൃത്യത"യും ഒന്നല്ല എന്ന് തിരിച്ചറിയുന്നതുവരെ മാത്രം. ഒരു ഡിസ്ട്രിബ്യൂട്ടഡ് സിസ്റ്റത്തിൽ (distributed system), ഇവന്റുകൾ പ്രകാശവേഗതയിൽ സഞ്ചരിച്ചാലും തെറ്റായ ക്രമത്തിൽ വന്നേക്കാം. WebSockets കണക്ഷൻ നഷ്ടപ്പെടുകയും വീണ്ടും കണക്ട് ചെയ്യപ്പെടുകയും ചെയ്യാം. Message brokers പാക്കറ്റുകൾ വീണ്ടും അയച്ചേക്കാം. Background workers ടൈമൗട്ട് ക്യാൻസലേഷനുകൾക്കെതിരെ മത്സരിക്കേണ്ടി വരുന്നു. അതിന്റെ ഫലം? ഒരു ക്ലയന്റിന് ആദ്യം ഇവന്റ് 42 കാണാം, പിന്നെ ഇവന്റ് 40, തുടർന്ന് സിസ്റ്റം ഇതിനകം ഇവന്റ് 45-ൽ എത്തി എന്ന് അവകാശപ്പെടുന്ന ഒരു സ്നാപ്പ്ഷറ്റും കാണാം. നിങ്ങൾ ദീർഘനേരം നീണ്ടുനിൽക്കുന്ന ഏജന്റ് വർക്ക്ഫ്ലോകൾ (agent workflows) നിർമ്മിക്കുകയാണെങ്കിൽ, ഈ കുഴപ്പങ്ങൾ വെറുമൊരു അപൂർവ്വ സംഭവമല്ല (edge case). അത് ഒരു സാധാരണ അവസ്ഥയാണ് (baseline). ഡെലിവറി സമയത്തിൽ നിന്ന് ഏതാനും മില്ലിസെക്കൻഡുകൾ കുറയ്ക്കാൻ ശ്രമിക്കുന്നതിന് മുമ്പ് നിങ്ങളുടെ ഇവന്റുകളുടെ ക്രമം ശരിയാക്കുക.

"റിയൽ-ടൈം" എന്നതിന്റെ സങ്കീർണ്ണമായ യാഥാർത്ഥ്യം

റിയൽ-ടൈം എന്നത് ഒരു ട്രാൻസ്പോർട്ട് പ്രോപ്പർട്ടി (transport property) ആണ്. അത് ഒരു പാക്കറ്റ് എത്ര വേഗത്തിൽ ഒരു വയറിലൂടെ നീങ്ങുന്നു എന്ന് വിവരിക്കുന്നു, അല്ലാതെ അത് പറയുന്ന വിവരങ്ങൾ യുക്തിസഹമാണോ എന്ന് അല്ല. ദീർഘനേരം നീണ്ടുനിൽക്കുന്ന ജോലികൾ (long-running tasks) സമയപരിധിയിൽ വ്യാപിച്ചു കിടക്കുന്നതിനാൽ എല്ലാ അസ്ഥിരതകളെയും വർദ്ധിപ്പിക്കുന്നു. ഒരു മോഡൽ ട്രെയിനിംഗ് ജോബ്, മൾട്ടി-സ്റ്റെപ്പ് അപ്രൂവൽ ഫ്ലോ, അല്ലെങ്കിൽ ഒരു വീഡിയോ റെൻഡറിംഗ് പൈപ്പ്‌ലൈൻ എന്നിവ മിനിറ്റുകൾക്കോ മണിക്കൂറുകൾക്കോ ശേഷം ഡസൻ കണക്കിന് ഇവന്റുകൾ പുറപ്പെടുവിച്ചേക്കാം. ആ സമയത്തിനുള്ളിൽ എന്ത് തെറ്റും സംഭവിക്കാം.

ഒരു അക്നോളജ്‌മെന്റ് (acknowledgement) നഷ്ടപ്പെട്ടാൽ ഒരു ബ്രോക്കർ ഒരു മെസ്സേജ് വീണ്ടും അയച്ചേക്കാം. ഒരു ലോഡ് ബാലൻസർ രണ്ട് ഇവന്റുകളെ വ്യത്യസ്ത നെറ്റ്‌വർക്ക് പാതകളിലൂടെ റൂട്ട് ചെയ്തേക്കാം, ഇത് പുതിയ ഇവന്റ് ആദ്യം എത്താൻ കാരണമായേക്കാം. ഒരു ഡാറ്റാബേസിലേക്ക് എഴുതിയതിന് ശേഷം എന്നാൽ സക്സസ് ഇവന്റ് പബ്ലിഷ് ചെയ്യുന്നതിന് മുമ്പ് ഒരു വർക്കർ പ്രോസസ്സ് മരിച്ചേക്കാം, തുടർന്ന് രണ്ടാമതൊരു വർക്കർ ആ ജോലി ഏറ്റെടുക്കുകയും അതിന്റെ പുരോഗതി അറിയിക്കുകയും ചെയ്തേക്കാം. നിങ്ങളുടെ ഫ്രണ്ട്‌എൻഡ് ഏറ്റവും പുതിയ മെസ്സേജാണ് ഏറ്റവും കൃത്യമായത് എന്ന് കരുതിയാൽ, അത് ഒരിക്കലും നിലവിലില്ലാത്ത ഒരു അവസ്ഥ (state) കാണിക്കും. ഉപയോക്താക്കൾക്ക് ഒരു "completed" ബാഡ്ജ് പെട്ടെന്ന് "processing" എന്നതിലേക്ക് മാറുന്നതോ, അല്ലെങ്കിൽ അതിലും മോശമായി, റദ്ദാക്കിയ ഒരു ടാസ്ക് പെട്ടെന്ന് വീണ്ടും സജീവമാകുന്നതോ കാണേണ്ടി വരും. ക്രമമില്ലാത്ത വേഗത എന്നത് ഉയർന്ന ഫ്രെയിം റേറ്റിലുള്ള ആശയക്കുഴപ്പം മാത്രമാണ്.

സീക്വൻസ് നമ്പറുകളാണ് യഥാർത്ഥ ക്ലോക്ക്

ഇതിനുള്ള പരിഹാരം പ്രൊഡ്യൂസർ നിർമ്മിക്കുന്ന കർശനമായ, മോണോട്ടോണിക് (monotonic) സീക്വൻസ് നമ്പറുകളാണ്. സ്റ്റേറ്റ് മാറ്റുന്ന ഓരോ ഓപ്പറേഷനും, ഇടവേളകളോ തിരിച്ചടവുകളോ (rollbacks) ഇല്ലാതെ കൃത്യമായി ഒന്ന് വീതം കൂടുന്ന ഒരു നമ്പർ ലഭിക്കണം. ആ നമ്പർ ആ ഇവന്റിനൊപ്പം തന്നെ ഒരേ ട്രാൻസാക്ഷനിൽ (transaction) സൂക്ഷിക്കണം. ഡാറ്റാബേസ് റോ അപ്‌ഡേറ്റ് ചെയ്യുകയും എന്നാൽ സീക്വൻസ് കമിറ്റ് പരാജയപ്പെടുകയും ചെയ്താൽ, നിങ്ങൾ രണ്ടും റോളബാക്ക് ചെയ്യണം. ഇത് ലോജിക്കൽ ടൈംലൈനിനെ സ്റ്റേറ്റ് മാറ്റത്തിനൊപ്പം അറ്റോമിക് (atomic) ആയി നിലനിർത്തുന്നു.

ഇവന്റ് ഐഡികൾ (Event IDs) ഇപ്പോഴും ഉപയോഗപ്രദമാണ്, പക്ഷേ അവ മറ്റൊരു പ്രശ്നമാണ് പരിഹരിക്കുന്നത്. ഒരു ബ്രോക്കർ ഒരേ മെസ്സേജ് രണ്ടുതവണ അയക്കുമ്പോൾ അത് ഡ്യൂപ്ലിക്കേറ്റ് ആണെന്ന് തിരിച്ചറിയാൻ (deduplicate) ഒരു ഇവന്റ് ഐഡി സഹായിക്കുന്നു. എന്നാൽ ഒരു സീക്വൻസ് നമ്പർ, ആ പേലോഡ് അതിന്റെ കാരണപരമായ ശൃംഖലയിൽ (causal chain) എവിടെയാണെന്ന് പറഞ്ഞുതരുന്നു. അത് ഇടവേളകളെയും ക്രമത്തെയും വെളിപ്പെടുത്തുന്നു. ഒരു ടൈംസ്റ്റാമ്പ് (timestamp) ഇവ രണ്ടും ചെയ്യുന്നില്ല. ക്ലോക്കുകൾ വ്യതിയാനമുണ്ടാക്കാം (drift), NTP പിന്നോട്ട് നീങ്ങാം, വെർച്വൽ മെഷീനുകൾ നിർത്തിപ്പോകാം. ടൈംസ്റ്റാമ്പുകൾ "3 മിനിറ്റ് മുമ്പ് ആരംഭിച്ചു" എന്നതുപോലെയുള്ള പ്രദർശന ആവശ്യങ്ങൾക്കായി മാത്രം ഉപയോഗിക്കുക, ബിസിനസ് ലോജിക്കിനായുള്ള സോർട്ടിംഗ് കീയായി ഒരിക്കലും ഉപയോഗിക്കരുത്.

ക്ലയന്റ് എങ്ങനെയാണ് സ്ട്രീം കൈകാര്യം ചെയ്യേണ്ടത്

പ്രൊഡ്യൂസർ ഒരു മോണോട്ടോണിക് സീക്വൻസ് ഉറപ്പാക്കിക്കഴിഞ്ഞാൽ, കൺസ്യൂമർക്ക് ലളിതവും കർശനവുമായ നിയമങ്ങൾ ലഭിക്കുന്നു. ഇൻബൗണ്ട് സീക്വൻസ് നമ്പർ അവസാനമായി ഉപയോഗിച്ച നമ്പറിന് തുല്യമോ അതിൽ കുറവോ ആണെങ്കിൽ, അത് ഒഴിവാക്കുക. അത് ഒന്നുകിൽ ഒരു ഡ്യൂപ്ലിക്കേറ്റ് ആയിരിക്കാം അല്ലെങ്കിൽ കാലഹരണപ്പെട്ട ഒന്നായിരിക്കാം. സീക്വൻസ് നമ്പർ അവസാനമായി ഉപയോഗിച്ച നമ്പറിനേക്കാൾ കൃത്യം ഒന്ന് കൂടുതലാണെങ്കിൽ, അത് ഉടൻ തന്നെ നടപ്പിലാക്കുക. അതാണ് ശരിയായ രീതി (happy path). സീക്വൻസ് നമ്പർ പെട്ടെന്ന് മുന്നോട്ട് ചാടുകയാണെങ്കിൽ, ഉദാഹരണത്തിന് നിങ്ങൾ 12 പ്രതീക്ഷിക്കുകയും എന്നാൽ 15 ലഭിക്കുകയും ചെയ്താൽ, എന്തോ ഒന്ന് നഷ്ടപ്പെട്ടിട്ടുണ്ട് എന്നാണ് അർത്ഥം. പുതിയ ഇവന്റ് ബഫർ (buffer) ചെയ്യുക, തുടർന്ന് അടുത്ത പ്രതീക്ഷിക്കുന്ന സീക്വൻസിൽ നിന്ന് റീപ്ലേ (replay) ചെയ്യാൻ സെർവറോട് ആവശ്യപ്പെടുക. ഊഹിക്കരുത്. ഇടവേളകൾ പ്രശ്നമല്ലെന്ന് കരുതി മുന്നോട്ട് പോകരുത്.

ടെർമിനൽ സ്റ്റേറ്റുകളെ (Terminal states) മാറ്റാൻ കഴിയാത്തവയായി കണക്കാക്കണം. ഒരു ടാസ്ക് "completed", "failed", അല്ലെങ്കിൽ "cancelled" എന്ന് അടയാളപ്പെടുത്തിയാൽ, ആ ഓപ്പറേഷനായുള്ള പിന്നീടുള്ള ഏതൊരു സ്റ്റേറ്റ് മാറ്റവും ക്ലയന്റ് നിരസിക്കണം. നിങ്ങൾ ഇതിനെ നേരിടുന്നത് വരെ ഇത് വളരെ വ്യക്തമായി തോന്നാം