દરેક Node.js ડેવલપર વહેલા કે મોડા એક જ સમસ્યાનો સામનો કરે છે. યુઝર એક બટન પર ક્લિક કરે છે, તમારો રૂટ હેન્ડલર કોઈ ભારે કામમાં વ્યસ્ત થઈ જાય છે, અને HTTP રિક્વેસ્ટ ત્યાં જ અટકી જાય છે. કદાચ તમે બેચમાં ઈમેલ મોકલી રહ્યા છો, થર્ડ-પાર્ટી CRM સાથે રેકોર્ડ્સ સિંક કરી રહ્યા છો, અથવા PDF રિપોર્ટ જનરેટ કરી રહ્યા છો. બ્રાઉઝર લોડિંગ બતાવશે. મોબાઈલ એપ ટાઈમ-આઉટ થઈ જશે. તમારા યુઝર્સ નારાજ થશે, અને તમારું સર્વર એવા કનેક્શન સ્લોટ્સ ગુમાવશે જે તે સહન કરી શકતું નથી. આનો ઉકેલ એ છે કે તે કામને રિક્વેસ્ટ પાથમાંથી બહાર કાઢીને Redis આધારિત બેકગ્રાઉન્ડ જોબ ક્યુ (background job queue) માં ખસેડવું. Node.js ઇકોસિસ્ટમમાં, બે લાઇબ્રેરીઓ આ ક્ષેત્રમાં પ્રભુત્વ ધરાવે છે: Bull અને BullMQ. તેમની વચ્ચે પસંદગી કરવાનો અર્થ વિજેતા પસંદ કરવો એવો નથી, પરંતુ તમારો પ્રોજેક્ટ અત્યારે ક્યાં છે અને કઈ દિશામાં જઈ રહ્યો છે તે સમજવો એવો છે.
The Original Workhorse
Bull વર્ષોથી Node.js બેકગ્રાઉન્ડ પ્રોસેસિંગ માટે સ્ટાન્ડર્ડ રહ્યું છે. તે સ્ટેબલ છે, વર્ષોના અનુભવથી પરખાયેલું છે, અને અસંખ્ય પ્રોડક્શન એપ્લિકેશન્સમાં ચાલે છે. જો તમારે કોઈ જોબ પછીના સમય માટે શેડ્યૂલ કરવી હોય, નિષ્ફળ થયેલ ઈમ્પોર્ટને આપમેળે ફરીથી પ્રયાસ (retry) કરવો હોય, અથવા પેમેન્ટ વેબહૂક ન્યૂઝલેટર મોકલતા પહેલા ચાલે તે માટે કડક પ્રાથમિકતા (priority) આપવી હોય, તો Bull તે બધું સરળતાથી સંભાળી લે છે. તેનું API callback-oriented છે, જેનો અર્થ છે કે તે જૂના કોડબેઝમાં સરળતાથી ફિટ થઈ જાય છે જ્યાં promises હજુ નવું હતું. જે ટીમો લાંબા સમયથી Bull પર નિર્ભર છે તેઓ જાણે છે કે શું અપેક્ષા રાખવી. આ લાઇબ્રેરી Redis માં સ્ટેટ (state) રાખે છે, તેથી જો તમારી Node પ્રોસેસ ફરીથી શરૂ થાય, તો પણ જોબ્સ સુરક્ષિત રહે છે. આ વિશ્વસનીયતાને કારણે જ ઘણા વ્યવસાયોએ પહેલેથી જ કામ કરતા સિસ્ટમમાં ફેરફાર કરવાની જરૂર અનુભવી નથી.
What BullMQ Changes
BullMQ એ તેનો ઉત્તરાધિકારી છે. તેને TypeScript માં સંપૂર્ણપણે ફરીથી બનાવવામાં આવ્યું છે, અને તેની આખી કાર્યક્ષમતા async/await ની આસપાસ બનાવવામાં આવી છે. જો તમે છેલ્લા કેટલાક વર્ષો આધુનિક Node.js કોડ લખવામાં વિતાવ્યા હોય, તો તેનું સિન્ટેક્સ તરત જ પરિચિત લાગશે. પરંતુ તફાવત માત્ર ટાઈપ ડેફિનેશન અને પ્રોમિસ ચેઈન પૂરતો મર્યાદિત નથી. BullMQ ક્યુ (queues) અને વર્કર્સ (workers) વચ્ચે સ્પષ્ટ અલગતા રાખે છે. Bull માં, ક્યુ ઘણીવાર વર્કર રનર તરીકે પણ કામ કરે છે. BullMQ માં, તમે એક ફાઇલમાં ક્યુ અને બીજી ફાઇલમાં વર્કર વ્યાખ્યાયિત કરો છો. આ અલગતા દર્શાવે છે કે પ્રોડક્શન સિસ્ટમ્સ ખરેખર કેવી રીતે સ્કેલ (scale) થાય છે. તમે વર્કર કન્ટેનર્સનો એક સમૂહ તૈનાત કરી શકો છો જે ફક્ત જોબ્સ પ્રોસેસ કરે છે, જ્યારે તમારા API સર્વર્સ ફક્ત ક્યુમાં જોબ્સ ઉમેરે છે. જેમ જેમ સિસ્ટમ વધતી જાય તેમ આ આર્કિટેક્ચર વાંચવામાં સરળ રહે છે.
Features That Tilt the Scale
BullMQ ખરેખર ક્યાં આગળ નીકળે છે તે તેની એવી કાર્યક્ષમતામાં છે જે Bull માં નથી. વાસ્તવિક એપ્લિકેશન્સમાં ત્રણ બાબતો સૌથી વધુ મહત્વની છે.
Job Flows
જટિલ વર્કફ્લો ભાગ્યે જ કોઈ એક બેકગ્રાઉન્ડ ફંક્શનમાં સમાઈ શકે છે. કલ્પના કરો કે તમે ઈમેજ પ્રોસેસિંગ પાઇપલાઇન બનાવી રહ્યા છો. યુઝર એક ફોટો અપલોડ કરે છે, અને તમારા બેકએન્ડને થંબનેલ બનાવવું, કોમ્પ્રેસ્ડ પ્રિવ્યૂ જનરેટ કરવો, OCR સ્કેન કરવું અને પછી ફ્રન્ટએન્ડને જાણ કરવી પડે છે કે બધું તૈયાર છે. Bull સાથે, તમે કદાચ આ તમામ સ્ટેપ્સને એક મોટા અને નાજુક હેન્ડલરમાં સમાવી દેશો. BullMQ 'job flows' રજૂ કરે છે, જે તમને પેરેન્ટ અને ચાઇલ્ડ જોબ્સને સ્પષ્ટ રીતે ચેઈન કરવા દે છે. તમે નિર્ભરતાઓ (dependencies) વ્યાખ્યાયિત કરી શકો છો જેથી નોટિફિકેશન સ્ટેપ ત્યારે જ ચાલે જ્યારે થંબનેલ અને OCR જોબ્સ બંને સફળ થાય. જો OCR નિષ્ફળ જાય, તો તમે થંબનેલને ફરીથી પ્રોસેસ કર્યા વગર ફક્ત તે જ ભાગને ફરીથી પ્રયાસ કરી શકો છો. લોજિક મોડ્યુલર, અવલોકનક્ષમ (observable) અને વહેલી સવારે કંઈક બગડે ત્યારે તેને ડિબગ કરવું ઘણું સરળ બની જાય છે.
Group Rate Limiting
જો તમે મલ્ટી-ટેનન્ટ SaaS એપ્લિકેશન ચલાવતા હોવ, તો તમે કદાચ એક ગ્રાહક દ્વારા તમારા વર્કર્સ પર વધુ પડતો લોડ આવવા વિશે ચિંતિત હશો. એક જ ટેનન્ટ દસ હજાર એક્સપોર્ટ જોબ્સ ક્યુમાં મૂકી શકે છે અને બીજા બધાને અવરોધી શકે છે. BullMQ ગ્રુપ રેટ લિમિટિંગ (group rate limiting) ઉમેરે છે, જે તમને ટેનન્ટ અથવા API કી દીઠ પ્રોસેસિંગને નિયંત્રિત કરવા દે છે. ઉદાહરણ તરીકે, તમે ટેનન્ટ A ને પ્રતિ મિનિટ પચાસ એક્સટર્નલ API કોલ્સ કરવાની મંજૂરી આપી શકો છો, જ્યારે ટેનન્ટ B ને સ્વતંત્ર રીતે સમાન મર્યાદા મળે છે. ક્યુ આ મર્યાદાઓનું પાલન તમામ વર્કર ઇન્સ્ટન્સમાં વૈશ્વિક સ્તરે કરે છે, માત્ર એક મશીન પર સ્થાનિક રીતે નહીં. આ એ પ્રકારનું સેફ્ટી વાલ્વ છે જેની તમે ક્યારેય કદર કરતા નથી જ્યાં સુધી તમને તેની અચાનક જરૂર ન પડે.
A Modern Surface
BullMQ જૂના (legacy) callback સિગ્નેચર છોડીને આધુનિક API અપનાવે છે. એરર હેન્ડલિંગ સ્ટાન્ડર્ડ પ્રોમિસ પેટર્નનું પાલન કરે છે. TypeScript ડેફિનેશન પ્રથમ સ્તરના (first-class) છે, તે કોઈ અલગ કોમ્યુનિટી પેકેજમાંથી ઉમેરેલી વસ્તુ નથી. જો તમે નવો (greenfield) પ્રોજેક્ટ શરૂ કરી રહ્યા હોવ, તો ડેવલપર એક્સપિરિયન્સ નોંધપાત્ર રીતે સરળ રહેશે. તમારું એડિટર ક્યુ ઓપ્શન્સને ઓટો-કમ્પ્લીટ કરશે. તમારું લિન્ટર ખૂટતા જોબ નામો પકડી લેશે. માનસિક બોજ (mental overhead) ઘટશે.
The Redis Constant
આ નિર્ણયમાં એક વ્યવહારુ રાહત ઈન્ફ્રાસ્ટ્રક્ચર છે. Bull અને BullMQ બંને જોબ સ્ટેટ, મેટાડેટા અને શેડ્યૂલ Redis માં સ્ટોર કરે છે. તેઓ અલગ-અલગ આંતરિક કી સ્ટ્રક્ચરનો ઉપયોગ કરે છે, પરંતુ તેની પાયાની ટેકનોલોજી સમાન છે. જો તમે Bull માટે પહેલેથી જ Redis ચલાવી રહ્યા હોવ, તો BullMQ અપનાવવા માટે તમારે નવું ડેટાબેઝ બદલવાની અથવા તમારા ડિપ્લોયમેન્ટ ટોપોલોજી વિશે ફરીથી વિચારવાની જરૂર નથી. માઈગ્રેશનનો પડકાર તમારા એપ્લિકેશન કોડમાં છે, તમારા સર્વર બિલમાં નહીં.
માઈગ્રેશનનું વાસ્તવિક સ્વરૂપ
તેમ છતાં, Bull થી BullMQ પર જવું એ સીધું બદલી શકાય તેવું (drop-in replacement) નથી. API કોલ્સ બદલાય છે. ઇવેન્ટના નામ અલગ હોય છે. તમે પ્રોસેસર્સ કેવી રીતે વ્યાખ્યાયિત કરો છો અને કન્કરન્સી (concurrency) કેવી રીતે હેન્ડલ કરો છો તે એટલું બદલાઈ જાય છે કે તમારે ક્યુ (queue) સાથે વાત કરતી દરેક ફાઇલને બદલવી પડશે. વધુ મહત્વનું એ છે કે, તમે માત્ર એક સ્વિચ ફ્લિપ કરીને એવી આશા રાખી શકતા નથી કે જૂની જોબ્સ નવા સિસ્ટમમાં પૂર્ણ થઈ જશે. સમાન Redis ઇન્સ્ટન્સ પર BullMQ વર્કર્સ શરૂ કરતા પહેલા તમારે તમારી હાલની Bull ક્યુઝને સંપૂર્ણપણે ખાલી કરવી પડશે. અન્યથા, તમે એક જ કીસ્પેસમાં બે અલગ-અલગ ફોર્મેટ અથડાવાનું જોખમ ઉઠાવો છો. મેન્ટેનન્સ વિન્ડો અથવા બ્લુ-ગ્રીન કટઓવર (blue-green cutover) માટે આયોજન કરો. આમાં ખરેખર મહેનત લાગે છે, અને તે મહેનત ફળદાયી હોવી જોઈએ.
ક્યાં પહોંચવું જોઈએ
જો તમારું હાલનું Bull સેટઅપ કોઈપણ ફરિયાદ વગર બરાબર ચાલી રહ્યું હોય, તો તેને એમ જ રહેવા દો. સ્થિરતાનું મૂલ્ય છે. બેકગ્રાઉન્ડ ક્યુ એ ઈન્ફ્રાસ્ટ્રક્ચર છે, કોઈ ફેશન સ્ટેટમેન્ટ નથી. જો તમારી ટીમ આર્કિટેક્ચર સામે લડી રહી હોય કારણ કે તમને પેરેન્ટ-ચાઈલ્ડ વર્કફ્લો અથવા પેર-ટેનન્ટ રેટ લિમિટ્સની ખૂબ જરૂર હોય, તો માઈગ્રેશન યોગ્ય છે. કાર્યોનું સ્પષ્ટ વિભાજન (separation of concerns) અને આધુનિક API સમય જતાં તમારા પ્રયત્નોનું વળતર આપશે.
કોઈપણ નવા પ્રોજેક્ટ માટે, પસંદગી સરળ છે. BullMQ થી શરૂઆત કરો. તે નિયમિત અપડેટ્સ મેળવે છે, હાલના JavaScript સ્ટાન્ડર્ડ્સને સીધું જ સપોર્ટ કરે છે, અને તમને છ મહિનામાં લાઈબ્રેરી નાની પડી જાય તે વગર જટિલ જોબ ફ્લો બનાવવા માટે પૂરતી ક્ષમતા આપે છે. તમે એવા API પર ટેકનિકલ ડેબ્ટ (technical debt) બનાવવાનું ટાળો છો જેનાથી મેન્ટેનર્સ પહેલેથી જ આગળ વધી ગયા છે.
મુખ્ય સારાંશ
જોબ ક્યુનો અસ્તિત્વ તમારા HTTP પ્રતિસાદો ઝડપી રાખવા અને તમારા વપરાશકર્તાઓને ધીરજવાન રાખવા માટે છે. Bull હજુ પણ તે કામ પ્રશંસનીય રીતે કરે છે. BullMQ તે એવા માળખા સાથે કરે છે જે આધુનિક Node.js એપ્લિકેશન્સ કેવી રીતે બનાવવામાં આવે છે અને સ્કેલ કરવામાં આવે છે તેની સાથે સુસંગત છે. પ્રશ્ન એ નથી કે કોઈ સંદર્ભ વગર કઈ લાઈબ્રેરી વધુ સારી છે. પ્રશ્ન એ છે કે શું તમારું વર્તમાન સંઘર્ષ માઈગ્રેશન કરવા લાયક છે, અને શું તમારો આગામી પ્રોજેક્ટ એવા પાયાને લાયક છે જેને તમારા આગામી ફંડિંગ રાઉન્ડ અથવા પ્રોડક્ટ લોન્ચ પહેલા બદલવાની જરૂર ન પડે.
