ഉപയോക്താവ് സെൻഡ് ബട്ടൺ തുടർച്ചയായി അമർത്തുമ്പോൾ, ബോട്ട് ഒരേ ഉത്തരം തന്നെ രണ്ട് മൂന്ന് തവണ നൽകാൻ തുടങ്ങി. AI ചിന്തിച്ചു തുടങ്ങുന്നതിന് മുമ്പ് തന്നെ വേഗത്തിൽ ഒന്നിലധികം സന്ദേശങ്ങൾ അയക്കുന്നവർക്ക് മാത്രമാണ് ഈ ഡ്യൂപ്ലിക്കേഷൻ (ആവർത്തനം) കണ്ടുവന്നത്. ഇത് പ്രൊഡക്ഷനിൽ ദീർഘകാലം ഒളിഞ്ഞിരുന്നു കാരണം ഈ രീതി അപൂർവ്വമായിരുന്നു. അകാലത്തിൽ അവസാനിച്ച ഒരു ഡാറ്റാബേസ് ലോക്ക് - ലോക്ക് ചെയ്തതിന് ഏതാനും മില്ലിസെക്കൻഡുകൾക്ക് ശേഷം അത് റിലീസ് ചെയ്യപ്പെട്ടു - സംഭാഷണത്തെ സുരക്ഷിതമല്ലാതാക്കി, ഇത് ഒരേ പ്രോംപ്റ്റിന് തന്നെ ഒന്നിലധികം പ്രോസസ്സുകൾ മറുപടി നൽകാൻ ഇടയാക്കി.

ലോക്ക് പരാജയപ്പെട്ടത് എന്തുകൊണ്ട്

കോഡ് ഒരു സിംഗിൾ ഡാറ്റാബേസ് കോളിലൂടെ ഒരു ലോക്ക് നേടിയെടുത്തു, തുടർന്ന് ഉടൻ തന്നെ അതിന്റെ നിയന്ത്രണം റിക്വസ്റ്റ് ഹാൻഡ്‌ലറിലേക്ക് തിരിച്ചുനൽകി. ലോക്കിന്റെ ആയുസ്സ് മില്ലിസെക്കൻഡുകളിൽ മാത്രമായിരുന്നു, ഇത് ഒരു മറുപടി നൽകാൻ AI മോഡലിന് ആവശ്യമായ സമയത്തേക്കാൾ വളരെ കുറവായിരുന്നു. മോഡൽ ജോലി തുടങ്ങുമ്പോഴേക്കും ലോക്ക് ഇല്ലാതായിക്കഴിഞ്ഞിരുന്നു, അതിനാൽ രണ്ടാമതൊരു റിക്വസ്റ്റ് അതേ സംഭാഷണ റെക്കോർഡ് എടുത്ത് മറ്റൊരു മറുപടി നൽകുന്നത് തടയാൻ ഒന്നും ഉണ്ടായിരുന്നില്ല.

രണ്ട് ലക്ഷണങ്ങൾ പുറത്തുവന്നു:

  • ഒരേ മറുപടികൾ തുടർച്ചയായി അയക്കപ്പെട്ടു.
  • ഒരേ ചോദ്യത്തിന് തന്നെ അല്പം വ്യത്യാസമുള്ള മറുപടികൾ പ്രത്യക്ഷപ്പെട്ടു, കാരണം ഓരോ പ്രോസസ്സും ഒരേ യൂസർ ഇൻപുട്ടിൽ നിന്ന് സ്വന്തമായി പ്രോംപ്റ്റുകൾ നിർമ്മിക്കുകയായിരുന്നു.

മിക്ക ഉപയോക്താക്കളും സന്ദേശങ്ങൾക്കിടയിൽ ഇടവേള എടുക്കുന്നതിനാൽ, ഈ ബഗ് ശ്രദ്ധയിൽപ്പെടാതെ പോയി. വേഗത്തിൽ ടൈപ്പ് ചെയ്യുന്നവർക്ക് മാത്രമേ ഈ റേസ് കണ്ടീഷൻ (race condition) സംഭവിക്കുമായിരുന്നുള്ളൂ, കൂടാതെ ഇത്തരം കേസുകൾ വളരെ അപൂർവ്വമായിരുന്നു.

ഫലപ്രദമല്ലാത്ത ആദ്യകാല പരിഹാരം

വേഗത്തിലുള്ള ഇൻപുട്ടുകളെ "ഡീബൗൺസ്" (debounce) ചെയ്യാൻ ലക്ഷ്യമിട്ട്, ഒരു സന്ദേശം ലഭിച്ചതിന് ശേഷം ചെറിയൊരു ഇടവേള നൽകുക എന്നതായിരുന്നു ആദ്യത്തെ പരിഹാരം. രണ്ട് സന്ദേശങ്ങൾ പെട്ടെന്ന് തുടർച്ചയായി വരുമ്പോൾ ഇത് സഹായിച്ചുവെങ്കിലും, AI ടെക്സ്റ്റ് നിർമ്മിച്ചുകൊണ്ടിരിക്കുമ്പോൾ തന്നെ മൂന്നാമതൊരു സന്ദേശം വന്നാൽ ഇത് പരാജയപ്പെട്ടു.

ടൈമറുകളും സംഭാഷണ ഡാറ്റയും ഒരേ സ്റ്റോറേജ് ബക്കറ്റിൽ സൂക്ഷിച്ചപ്പോൾ രണ്ടാമതൊരു പ്രശ്നം കൂടി ഉടലെടുത്തു. ബോട്ട് ഒരു റിക്വസ്റ്റ് പ്രോസസ്സ് ചെയ്തുകഴിഞ്ഞാൽ, അത് ടൈമർ റെക്കോർഡിനെ ഓവർറൈറ്റ് ചെയ്യുകയും തങ്ങളുടെ കൗണ്ട്ഡൗൺ തന്നെ ഡിലീറ്റ് ചെയ്യുകയും ചെയ്തു. ഏതെല്ലാം സന്ദേശങ്ങൾക്കാണ് മറുപടി നൽകിയതെന്ന് സിസ്റ്റത്തിന് തിരിച്ചറിയാൻ കഴിയാതെ വന്നു, ഇത് കൂടുതൽ ഡ്യൂപ്ലിക്കേഷനുകൾക്ക് കാരണമായി.

വിശ്വസനീയമായ ഒരു സുരക്ഷാ സംവിധാനം നിർമ്മിക്കുന്നു: വേർഷൻ കൗണ്ടറുകൾ, ഐസൊലേറ്റഡ് ടൈമറുകൾ, ഒരു ലീസ് (lease)

ടീം മൂന്ന് പ്രധാന കാര്യങ്ങളെ അടിസ്ഥാനമാക്കി പ്രവർത്തനരീതി പുനർരൂപകൽപ്പന ചെയ്തു:

  • വേർഷൻ കൗണ്ടർ (Version counter) – ഓരോ പുതിയ സന്ദേശവും സംഭാഷണത്തോടൊപ്പം സൂക്ഷിച്ചിരിക്കുന്ന ഒരു കൗണ്ടർ വർദ്ധിപ്പിക്കുന്നു. ഒരു മറുപടി തയ്യാറാക്കിക്കൊണ്ടിരിക്കുമ്പോൾ പുതിയ ഇൻപുട്ടുകൾ വന്നിട്ടുണ്ടോ എന്ന് കണ്ടെത്താൻ ഈ കൗണ്ടർ സിസ്റ്റത്തെ സഹായിക്കുന്നു.
  • പ്രത്യേക ഡീബൗൺസ് വിൻഡോ (Dedicated debounce window) – ടൈമറുകൾ ഇപ്പോൾ സംഭാഷണ ഡാറ്റയിൽ നിന്ന് വേറിട്ട് ഒരു പ്രത്യേക സ്റ്റോറേജ് ഏരിയയിൽ സൂക്ഷിക്കുന്നു. ഡീബൗൺസ് സമയത്തിന് ഒരു പരിധി നിശ്ചയിച്ചിട്ടുള്ളതിനാൽ ഉപയോക്താവിന് ബോട്ടിനെ അനാവശ്യമായി തടഞ്ഞുവെക്കാൻ കഴിയില്ല.
  • സെഷൻ ലീസ് (Session lease) – പഴയ ലോക്കിന് പകരം കൃത്യമായ എക്സ്പയറി ടൈംസ്റ്റാമ്പ് (expiry timestamp) ഉള്ള ഒരു ലീസ് ഉപയോഗിക്കുന്നു. കംപയർ-ആൻഡ്-സ്വാപ്പ് (compare-and-swap - CAS) ഓപ്പറേഷൻ ഉപയോഗിച്ചാണ് ലീസ് കൈക്കലാക്കുന്നത്: പ്രോസസ്സ് നിലവിലെ ലീസ് വാല്യൂ വായിക്കുന്നു, പഴയ വാല്യൂ ശരിയാണെങ്കിൽ മാത്രം പുതിയ വാല്യൂ എഴുതുന്നു, അങ്ങനെ സംഭാഷണത്തിന്മേൽ തനിക്ക് മാത്രം അവകാശം ലഭിക്കുന്നു എന്ന് ഉറപ്പാക്കുന്നു. പ്രോസസ്സ് ക്രാഷ് ആയാൽ ലീസ് തനിയെ എക്സ്പയർ ചെയ്യുകയും അടുത്ത ഹാൻഡ്‌ലറിലേക്ക് സംഭാഷണം ലഭ്യമാവുകയും ചെയ്യുന്നു.

പുതിയ പൈപ്പ്‌ലൈൻ എങ്ങനെ പ്രവർത്തിക്കുന്നു

  1. സന്ദേശം ലഭിക്കുന്നു (Message arrival) – സിസ്റ്റം വേർഷൻ കൗണ്ടർ വർദ്ധിപ്പിക്കുകയും ഡീബൗൺസ് ടൈമർ (re)set ചെയ്യുകയും ചെയ്യുന്നു. AI പ്രവർത്തിപ്പിക്കാതെ തന്നെ ഇത് ഉടൻ തന്നെ ക്ലയന്റിന് മറുപടി നൽകുന്നു.
  2. ടൈമർ അവസാനിക്കുന്നു (Timer expiration) – ടൈമർ ഹാൻഡ്‌ലർ ലീസ് കൈക്കലാക്കാൻ ശ്രമിക്കുന്നു. CAS വിജയിച്ചാൽ ഹാൻഡ്‌ലർ മുന്നോട്ട് പോകുന്നു; അല്ലെങ്കിൽ മറ്റൊരു പ്രോസസ്സ് ഇതിനകം സംഭാഷണം കൈകാര്യം ചെയ്യുന്നുണ്ടെന്ന് മനസ്സിലാക്കി അത് പിന്മാറുന്നു.
  3. പുതിയ ഇൻപുട്ട് പരിശോധിക്കുന്നു (Check for new input) – ഹാൻഡ്‌ലർ നിലവിലെ വേർഷൻ കൗണ്ടറിനെ ടൈമർ തുടങ്ങിയ സമയത്തെ കൗണ്ടറുമായി താരതമ്യം ചെയ്യുന്നു. കൗണ്ടർ വർദ്ധിച്ചിട്ടുണ്ടെങ്കിൽ, നിലവിലുള്ള സന്ദേശങ്ങളെല്ലാം ചേർത്ത് ഒരു ഒറ്റ പ്രോംപ്റ്റ് തയ്യാറാക്കുന്നു.
  4. മറുപടി നൽകുന്നു (Generate a reply) – AI മോഡൽ ഒരു തവണ മാത്രം പ്രവർത്തിക്കുകയും, സമീപകാലത്തെ എല്ലാ ഇൻപുട്ടുകൾക്കും ഉൾക്കൊള്ളുന്ന ഒരൊറ്റ മറുപടി നൽകുകയും ചെയ്യുന്നു.
  5. അവസാന പരിശോധന (Final sanity check) – മറുപടി അയക്കുന്നതിന് തൊട്ടുമുമ്പ്, ഹാൻഡ്‌ലർ വീണ്ടും വേർഷൻ കൗണ്ടർ പരിശോധിക്കുന്നു. മറുപടി തയ്യാറാക്കുന്നതിനിടെ പുതിയ സന്ദേശങ്ങൾ വന്നിട്ടുണ്ടെങ്കിൽ, ആ മറുപടി ഒഴിവാക്കുകയും ടൈമർ വീണ്ടും റീസ്റ്റാർട്ട് ചെയ്യുകയും ചെയ്യുന്നു. ഇത് ഉപയോക്താവിന് തെറ്റായ മറുപടികൾ ലഭിക്കുന്നത് തടയുന്നു.

ഈ രീതി ഡ്യൂപ്ലിക്കേറ്റ് മറുപടികൾ ഒഴിവാക്കുന്നു, സംഭാഷണം തടസ്സപ്പെട്ടു കിടക്കുന്ന സമയം പരിമിതപ്പെടുത്തുന്നു, കൂടാതെ പ്രോസസ്സ് ക്രാഷ് ആയാൽ ലീസ് തനിയെ എക്സ്പയർ ചെയ്യുന്നതിനാൽ സിസ്റ്റം സ്വയം വീണ്ടെടുക്കുകയും ചെയ്യുന്നു.

പാഠം

പ്രധാനപ്പെട്ട ഘട്ടം തുടങ്ങുന്നതിന് മുമ്പ് തന്നെ ഇല്ലാതാകുന്ന ഒരു ലോക്ക് യാതൊരു സംരക്ഷണവും നൽകുന്നില്ല. ഒരു ഡാറ്റാബേസ് ലോക്കിന് പകരം കൃത്യമായ എക്സ്പയറി ടൈംസ്റ്റാമ്പ് ഉള്ള ഒരു ലീസ് ഉപയോഗിക്കുന്നതിലൂടെയും, ടൈമറുകളെ സംഭാഷണ ഡാറ്റയിൽ നിന്ന് വേർതിരിക്കുന്നതിലൂടെയും, ഉപയോക്താക്കൾ വളരെ വേഗത്തിൽ ടൈപ്പ് ചെയ്യുമ്പോഴും കൃത്യമായ മറുപടി നൽകാൻ ബോട്ടിന് ഇപ്പോൾ സാധിക്കുന്നു. ഒരു കാര്യം ഇവിടെ വ്യക്തമാണ്: കോൺകറൻസി സുരക്ഷാ സംവിധാനങ്ങൾ (concurrency safeguards) അവ സംരക്ഷിക്കുന്ന ജോലിയേക്കാൾ കൂടുതൽ സമയം നിലനിൽക്കേണ്ടതുണ്ട്, അല്ലെങ്കിൽ അവ ബഗുകൾ കടന്നുപോകാൻ അനുവദിക്കുന്ന അദൃശ്യമായ തടസ്സങ്ങളായി മാറും.