Laravel 13.31 interruptible jobs ചേർക്കുന്നു, ഇത് ക്യൂ വർക്കർമാരെ (queue workers) ഡിപ്ലോയ്മെന്റുകൾ സമയത്ത് അയക്കുന്ന SIGTERM സിഗ്നൽ സ്വീകരിക്കാനും, ഒരു ടാസ്ക് പകുതിക്ക് വെച്ച് പാതിവഴിയിൽ നിർത്തുന്നതിന് പകരം സുഗമമായി ഷട്ട്ഡൗൺ ചെയ്യാനും അനുവദിക്കുന്നു. പതിനായിരക്കണക്കിന് വരികൾ പ്രോസസ്സ് ചെയ്യുന്നതോ, ബൾക്ക് ഇമെയിലുകൾ അയക്കുന്നതോ, റിപ്പോർട്ടുകൾ തയ്യാറാക്കുന്നതോ ആയ ദീർഘനേരം എടുക്കുന്ന ജോബുകൾ നടത്തുന്ന ടീമുകൾക്ക് ഇത് വലിയ ഗുണകരമാണ്, കാരണം പുതിയ റിലീസ് വരുമ്പോൾ ഡാറ്റാ സ്ഥിരത (data consistency) നിലനിർത്താൻ ഇത് സഹായിക്കുന്നു.
എന്തുകൊണ്ടാണ് ഡിപ്ലോയ്മെന്റുകൾ ജോബുകളെ തകരാറിലാക്കുന്നത്
ഒരു പുതിയ വേർഷൻ വരുമ്പോൾ, Supervisor, Docker, Kubernetes തുടങ്ങിയ പ്രോസസ് മാനേജർമാർ നിലവിലുള്ള വർക്കർമാരോട് നിർത്താൻ SIGTERM അയക്കുന്നു; ഇത് പ്രവർത്തനം അവസാനിപ്പിക്കാനുള്ള ഒരു മാന്യമായ അഭ്യർത്ഥനയാണ്. മിക്ക വർക്കർമാരും നിലവിലെ ജോലി പൂർത്തിയാക്കിയ ശേഷം മാത്രമേ പുറത്തുകടക്കുന്നുള്ളൂ. എന്നാൽ മാനേജർ ഇതിനായി ഏതാനും സെക്കൻഡുകൾ മാത്രമേ അനുവദിക്കുന്നുള്ളൂ എങ്കിൽ പ്രശ്നം ഉണ്ടാകുന്നു. ഒരു ജോലിക്ക് മിനിറ്റുകൾ ആവശ്യമാണെങ്കിൽ, മാനേജർ SIGKILL ലേക്ക് മാറുകയും പ്രോസസ്സ് പെട്ടെന്ന് അവസാനിപ്പിക്കുകയും ചെയ്യുന്നു. ഇത് ജോലി ഒരിക്കലും ഒരു സ്ഥിരമായ അവസ്ഥയിൽ (consistent state) എത്തിക്കുന്നില്ല, തൽഫലമായി ഭാഗികമായി അപ്ഡേറ്റ് ചെയ്ത റെക്കോർഡുകൾ, അനാഥമായ ഫയലുകൾ (orphaned files), അല്ലെങ്കിൽ ഡ്യൂപ്ലിക്കേറ്റ് ജോലികൾ എന്നിവ ഉണ്ടാകുന്നു.
Laravel-ന്റെ പരിഹാരം: സഹകരണാധിഷ്ഠിത തടസ്സപ്പെടുത്തൽ (cooperative interruption)
Laravel 13.31-ൽ Interruptible എന്ന പേരിൽ ഒരു കോൺട്രാക്ട് അവതരിപ്പിച്ചിട്ടുണ്ട്. ഒരു ജോബ് ക്ലാസ്സിന് ഈ കോൺട്രാക്ട് നടപ്പിലാക്കുന്നതിലൂടെ (implement) ടെർമിനേഷൻ അഭ്യർത്ഥനകളെക്കുറിച്ച് ബോധവാന്മാരാകാൻ സാധിക്കും. SIGTERM ലഭിക്കുമ്പോൾ, Laravel ജോബിന്റെ interrupted() മെത്തേഡ് വിളിക്കുന്നു. ഫ്രെയിംവർക്ക് ജോബിനെ സ്വയമേവ നിർത്തുന്നില്ല; പകരം, Laravel സെറ്റ് ചെയ്യുന്ന ഒരു ഫ്ലാഗ് (flag) ജോബ് പരിശോധിക്കുകയും സ്വയം പുറത്തുകടക്കുകയും (exit) വേണം. ഈ സഹകരണാധിഷ്ഠിത മോഡൽ ഉപയോഗിച്ച് ഡെവലപ്പർമാർക്ക് നിലവിലെ ലൂപ്പ് ഇറ്ററേഷൻ പൂർത്തിയാക്കാനോ, ഭാഗികമായ മാറ്റങ്ങൾ റോളബാക്ക് ചെയ്യാനോ, അല്ലെങ്കിൽ നിർത്തുന്നതിന് മുമ്പ് ഒരു ചെക്ക്പോയിന്റ് എഴുതാനോ സാധിക്കുന്നു.
ഒരു ജോബിനെ interruptible ആക്കുന്നത് എങ്ങനെ
- കോൺട്രാക്ട് നടപ്പിലാക്കുക – ജോബ് ക്ലാസ്സ് ഡെഫനിഷനിൽ
implements Interruptibleഎന്ന് ചേർക്കുക. - വർക്ക് ലൂപ്പിനുള്ളിൽ ഫ്ലാഗ് പരിശോധിക്കുക – ജോലി നിർത്തണോ എന്ന് പരിശോധിക്കാൻ ഓരോ ഇറ്ററേഷനിലും ഒരു ചെക്ക് ഉൾപ്പെടുത്തുക.
- ക്ലീനപ്പ് നടത്തുക –
interrupted()മെത്തേഡിൽ, ജോലി പിന്നീട് പുനരാരംഭിക്കാൻ സഹായിക്കുന്ന വിവരങ്ങൾ സേവ് ചെയ്യുകയോ അല്ലെങ്കിൽ വിശകലനത്തിനായി തടസ്സപ്പെടുത്തൽ ലോഗ് ചെയ്യുകയോ ചെയ്യുക.
ഏറ്റവും വലിയ കെണി: --once ഉപയോഗിക്കരുത്
php artisan queue:work --once ഉപയോഗിച്ച് ക്യൂ വർക്കർ പ്രവർത്തിപ്പിക്കുന്നത് സിഗ്നൽ ഹാൻഡ്ലിംഗിനെ പൂർണ്ണമായും ഇല്ലാതാക്കുന്നു. വർക്കർ ഒരു ജോബ് പ്രോസസ്സ് ചെയ്ത് പുറത്തുകടക്കും, എന്നാൽ അത് ഒരിക്കലും SIGTERM ഹാൻഡ്ലർ രജിസ്റ്റർ ചെയ്യില്ല. തൽഫലമായി, ഏതൊരു interruptible ജോബും ടെർമിനേഷൻ അഭ്യർത്ഥന അവഗണിക്കുകയും പ്രോസസ്സിനിടെ കൊല്ലപ്പെടുകയും ചെയ്യുന്നു. ക്രോൺ (cron) ഉപയോഗിച്ച് പ്രവർത്തിക്കുന്ന കണ്ടെയ്നറുകളിലും വൺ-ഷോട്ട് ഡിപ്ലോയ്മെന്റുകളിലും ഈ രീതി കാണാറുണ്ട്. interruptible ജോബുകൾ ആവശ്യമുള്ളപ്പോഴെല്ലാം ഡെമൺ മോഡിൽ (php artisan queue:work) പ്രവർത്തിപ്പിച്ചുകൊണ്ട് ഇത് പരിഹരിക്കുക.
തടസ്സപ്പെടുത്തലുകൾ നിരീക്ഷിക്കുക
നിങ്ങൾക്ക് ഉപയോഗിക്കാൻ കഴിയുന്ന രണ്ട് ഇവന്റുകൾ Laravel ഫയർ ചെയ്യുന്നു:
- WorkerInterrupted – ഏതെങ്കിലും വർക്കർ SIGTERM സ്വീകരിക്കുമ്പോൾ ഇത് പുറപ്പെടുവിക്കുന്നു. ഡിപ്ലോയ്മെന്റുകൾ എത്രത്തോളം വർക്കർമാരെ തടസ്സപ്പെടുത്തുന്നു എന്നതിനെക്കുറിച്ച് ഒരു ഉയർന്ന തലത്തിലുള്ള കാഴ്ചപ്പാട് ഇതിലൂടെ ലഭിക്കും.
- JobInterrupted – നിലവിലെ ജോബ് Interruptible കോൺട്രാക്ട് നടപ്പിലാക്കിയിട്ടുണ്ടെങ്കിൽ മാത്രമേ ഇത് പുറപ്പെടുവിക്കൂ. താത്കാലിക ഫയലുകൾ നീക്കം ചെയ്യുകയോ അല്ലെങ്കിൽ "അവസാനമായി പ്രോസസ്സ് ചെയ്ത വരി" (last processed row) മാർക്കർ അപ്ഡേറ്റ് ചെയ്യുകയോ പോലുള്ള ജോബ്-സ്പെസിഫിക് ക്ലീനപ്പുകൾക്കായി ഈ ഇവന്റ് ഉപയോഗിക്കാം.
ഈ ഇവന്റുകൾ ശ്രദ്ധിക്കുന്നതിലൂടെ, ഡിപ്ലോയ്മെന്റുകളുടെ സ്വാധീനം കാണിക്കുന്ന ഡാഷ്ബോർഡുകൾ നിർമ്മിക്കാനും ഇടയ്ക്ക് മുറിഞ്ഞുപോകുന്ന ജോബുകൾ കണ്ടെത്താനും ടീമുകൾക്ക് സാധിക്കും.
ക്യൂ സൈസ് റിപ്പോർട്ടിംഗിൽ ചെറിയ മാറ്റം
ഈ റിലീസ് ക്യൂ മാനേജറിൽ totalSize() എന്ന ഒരു മെത്തേഡ് കൂടി ചേർക്കുന്നു, ഇത് എല്ലാ ക്യൂകളിലുമുള്ള നിലവിലുള്ള ജോബുകളുടെ ആകെ എണ്ണം തിരികെ നൽകുന്നു. ഡാറ്റാബേസ് അധിഷ്ഠിതവും Redis ഡ്രൈവറുകളും യഥാർത്ഥ എണ്ണം റിപ്പോർട്ട് ചെയ്യുന്നതിനാൽ ഈ മൂല്യം വിശ്വസനീയമാണ്. എന്നാൽ SQS, Sync, Beanstalkd തുടങ്ങിയ ഡ്രൈവറുകൾ ഇപ്പോഴും പൂജ്യം (zero) ആണ് കാണിക്കുന്നത്, കാരണം അവ Laravel-ന്റെ API വഴി കൗണ്ട് ലഭ്യമാക്കുന്നില്ല. SQS ഉപയോഗിക്കുന്ന ടീമുകൾ ക്യൂ ഡെപ്തിനായി (queue depth) CloudWatch മെട്രിക്സുകളെ ആശ്രയിക്കുന്നത് തുടരുക.
വിവിധ സെറ്റപ്പുകൾക്ക് ഇതിന്റെ അർത്ഥമെന്താണ്
- Docker/Kubernetes – സുഗമമായ ഷട്ട്ഡൗൺ കാലയളവ് (graceful shutdown period) ഇനി ഫലപ്രദമായി ഉപയോഗിക്കാം. ജോബുകൾക്ക് ഫ്ലാഗ് ശ്രദ്ധിക്കാനും സുഗമമായി പുറത്തുകടക്കാനും ഏതാനും സെക്കൻഡുകൾ ലഭിക്കുന്ന രീതിയിൽ ടെർമിനേഷൻ ഗ്രേസ് പിരീഡ് വർദ്ധിപ്പിക്കുക.
- Supervisor – ഇൻ്ററപ്റ്റ് ഫ്ലാഗ് ലഭിച്ചതിന് ശേഷം ഒരു ജോലി പൂർത്തിയാകാൻ നിങ്ങൾ പ്രതീക്ഷിക്കുന്ന സമയത്തേക്കാൾ കൂടുതൽ
stopwaitsecsആയി സെറ്റ് ചെയ്യുക. - Legacy jobs – മാനേജറുടെ ടൈമൗട്ടിനേക്കാൾ കൂടുതൽ സമയം എടുക്കുന്ന ജോബുകൾ പരിശോധിക്കുകയും സാധ്യമാണെങ്കിൽ അവയെ interruptible ആക്കി മാറ്റുകയും ചെയ്യുക.
മറ്റൊരു വശം: വർദ്ധിച്ച സങ്കീർണ്ണത
ഈ ഫീച്ചർ ശരിയായ ടൈമൗട്ട് കോൺഫിഗറേഷന് പകരമാകുന്നില്ല. ഒരു ജോബിന്റെ ലൂപ്പ് ഒരിക്കലും ഇൻ്ററപ്ഷൻ ഫ്ലാഗ് പരിശോധിക്കുന്നില്ലെങ്കിൽ, മാനേജർ ഇപ്പോഴും SIGKILL അയക്കും. ടീമുകൾ ദീർഘനേരം പ്രവർത്തിക്കുന്ന കോഡ് പാത്തുകൾ പരിശോധിക്കുകയും യുക്തിസഹമായ ഇടങ്ങളിൽ ചെക്കുകൾ ഉൾപ്പെടുത്തുകയും വേണം. ഷട്ട്ഡൗൺ വിൻഡോയ്ക്കുള്ളിൽ തന്നെ പൂർത്തിയാകുന്ന ചെറിയ ജോബുകൾക്ക്, ഒരു കോൺട്രാക്ട് നടപ്പിലാക്കുന്നതും ഫ്ലാഗ് ചെക്കുകൾ ചേർക്കുന്നതുമായ അധികമായ ബോയിലർപ്ലേറ്റ് (boilerplate) ജോലികൾ ചില ഡെവലപ്പർമാർക്ക് അനാവശ്യമായി തോന്നിയേക്കാം.
ആക്ഷൻ ചെക്ക്ലിസ്റ്റ്
- ഡിപ്ലോയ്മെന്റ് സ്ക്രിപ്റ്റുകളിൽ
--onceഫ്ലാഗ് ഉണ്ടോ എന്ന് പരിശോധിക്കുകയും, ഇന്ററപ്റ്റബിൾ ജോബുകൾ (interruptible jobs) ഉപയോഗിക്കുന്നിടത്ത് അത് ഡെമൺ മോഡിൽ (daemon mode) മാറ്റുകയും ചെയ്യുക. - ഏറ്റവും കൂടുതൽ സമയം എടുക്കുന്ന ജോബുകൾ (പതിനായിരക്കണക്കിന് വരികൾ കൈകാര്യം ചെയ്യുന്നതോ അല്ലെങ്കിൽ മിനിറ്റുകളോളം നീണ്ടുനിൽക്കുന്നതോ ആയവ) തിരിച്ചറിയുകയും അവയിൽ Interruptible contract ചേർക്കുകയും ചെയ്യുക.
- ഓരോ ലൂപ്പ് ഇറ്ററേഷനുള്ളിലും (loop iteration) ഒരു ഫ്ലാഗ് ചെക്ക് ഉൾപ്പെടുത്തുക, കൂടാതെ ആവശ്യമായ ഫൈനലൈസേഷൻ കോഡുകൾ
interrupted()മെത്തേഡിലേക്ക് മാറ്റുക. - ഡിപ്ലോയ്മെന്റുകൾ പ്രോസസ്സിംഗിനെ എത്രത്തോളം ബാധിക്കുന്നു എന്നതിനെക്കുറിച്ചുള്ള മെട്രിക്സുകൾ (metrics) ശേഖരിക്കുന്നതിനായി
WorkerInterrupted,JobInterruptedഎന്നിവയിലേക്ക് ലിസണറുകൾ (listeners) ഘടിപ്പിക്കുക. - Redis അല്ലെങ്കിൽ ഡാറ്റാബേസ് ക്യൂകൾക്കായി, ബാക്ക്ലോഗ് (backlog) നിരീക്ഷിക്കാൻ
totalSize()ഉപയോഗിക്കുക; SQS-ന് വേണ്ടി CloudWatch അലാറങ്ങൾ നിലനിർത്തുക.
ഡിപ്ലോയ്മെന്റ് മൂലമുണ്ടാകുന്ന ഷട്ട്ഡൗണുകളെ പെട്ടെന്നുള്ള ഒരു നിർത്തലാക്കലായി കാണാതെ, കൃത്യമായി ഏകോപിപ്പിച്ച ഒരു ഘട്ടമായി പരിഗണിക്കുക. Laravel 13.31 ഡാറ്റാ സ്ഥിരത നിലനിർത്തുകയും പകുതിക്ക് മുగిഞ്ഞ ജോബുകൾ മൂലമുണ്ടാകുന്ന പ്രവർത്തനപരമായ ബുദ്ധിമുട്ടുകൾ കുറയ്ക്കുകയും ചെയ്യുന്നു. ഇതിന് പകരമായി കോഡിംഗിൽ ചെറിയ തോതിൽ കൂടുതൽ ഉത്തരവാദിത്തം ആവശ്യമായി വരുന്നുണ്ടെങ്കിലും, കനത്ത ബാക്ക്ഗ്രൗണ്ട് പ്രോസസ്സിംഗിനെ ആശ്രയിക്കുന്ന ടീമുകൾക്ക് കൂടുതൽ വിശ്വസനീയമായ ഒരു പ്രൊഡക്ഷൻ എൻവയോൺമെന്റ് ഇതിലൂടെ ലഭിക്കുന്നു.
