The Cache Was Working, But It Still Caused Duplicate API Calls
કેશ બગડેલું નહોતું.
તેમ છતાં, એક જ યુઝરનેમ માટેના ત્રણ સમાંતર (concurrent) રિક્વેસ્ટ્સ GitHub પર ત્રણ વાર પહોંચ્યા.
આ CommitPulse માં થયું હતું, જે એક Next.js API છે જે GitHub ડેટાને SVG બેજમાં રૂપાંતરિત કરે છે. જ્યારે કોઈ README વાયરલ થાય છે, ત્યારે હજારો લોકો એકસાથે બેજ જુએ છે. આના કારણે ભારે ટ્રાફિક સર્જાય છે.
કેશ ક્રમિક (sequential) રિક્વેસ્ટ્સ માટે કામ કરતું હતું. પરંતુ સમાંતર (concurrent) રિક્વેસ્ટ્સ માટે તે નિષ્ફળ ગયું.
સમસ્યા અહીં છે:
- રિક્વેસ્ટ A કેશ ચેક કરે છે. તે 'miss' છે. રિક્વેસ્ટ A GitHub પરથી ડેટા મેળવવાનું (fetching) શરૂ કરે છે.
- રિક્વેસ્ટ B 5ms પછી આવે છે. તે કેશ ચેક કરે છે. તે હજુ પણ 'miss' છે કારણ કે રિક્વેસ્ટ A હજુ પૂરી થઈ નથી. રિક્વેસ્ટ B બીજું fetch શરૂ કરે છે.
- રિક્વેસ્ટ C 10ms પછી આવે છે. તે પણ કેશ miss જુએ છે અને ત્રીજું fetch શરૂ કરે છે.
આ 'thundering herd' સમસ્યા છે. વધુ લોડ હેઠળ કેશ miss થવાથી તમારા અપસ્ટ્રીમ પ્રોવાઈડર (upstream provider) પર સમાન કોલ્સનો પૂર આવી જાય છે. જો તમે GitHub જેવી રેટ-લિમિટેડ API નો ઉપયોગ કરતા હોવ, તો આ તમારા લિમિટ્સને તરત જ સમાપ્ત કરી શકે છે.
તેનો ઉકેલ 'request coalescing' છે.
તમારે પૂર્ણ થયેલ કેશ એન્ટ્રીઝથી અલગ રીતે પેન્ડિંગ રિક્વેસ્ટ્સને ટ્રેક કરવા જોઈએ. મેં આને મેનેજ કરવા માટે એક in-flight Map અમલમાં મૂક્યું છે:
- જ્યારે રિક્વેસ્ટ શરૂ થાય, ત્યારે તેનો Promise એક Map માં સ્ટોર કરો.
- જો તે જ કી (key) માટે બીજી રિક્વેસ્ટ આવે, તો નવું fetch શરૂ કરશો નહીં.
- તેના બદલે, Map માંથી હાલનો (existing) Promise રિટર્ન કરો.
- એકવાર રિક્વેસ્ટ પૂરી થઈ જાય, પછી તેને Map માંથી દૂર કરો અને પરિણામને કેશમાં સેવ કરો.
આ સુનિશ્ચિત કરે છે કે ગમે તેટલા લોકો એકસાથે સમાન ડેટા માટે રિક્વેસ્ટ કરે, API પર માત્ર એક જ કોલ જાય.
આને ઠીક કરતી વખતે, મેં તે જ ફાઇલમાં અન્ય ત્રણ એજ-કેસ (edge-case) બગ્સ પણ ઉકેલ્યા:
- Missing Token Errors: સિસ્ટમ ક્રેડેન્શિયલ તરીકે "undefined" મોકલતી હતી. મેં રિક્વેસ્ટ મોકલતા પહેલા ટોકન્સને વેલિડેટ કરવા માટે તેને અપડેટ કર્યું.
- Memory Leaks: રીટ્રાય લોજિક (Retry logic) AbortSignals પર જૂના (stale) ઇવેન્ટ લિસનર્સ છોડી દેતું હતું. મેં લીક અટકાવવા માટે ક્લીનઅપ લોજિક ઉમેર્યું.
- URL Injection: સ્પેશિયલ કેરેક્ટર ધરાવતા યુઝરનેમ્સ API પાથને તોડી નાખતા હતા. મેં URL સ્ટ્રક્ચરને સુરક્ષિત કરવા માટે એન્કોડિંગ ઉમેર્યું.
માત્ર કેશ પૂરતું નથી. તમારે હાલમાં ચાલતી (in flight) રિક્વેસ્ટ્સને પણ ડુપ્લીકેટ થતી અટકાવવી (deduplicate) પડશે.
Source: https://dev.to/eshaanagrawal/the-cache-was-working-and-still-causing-duplicate-api-calls-3n51
