கேச் சரியாக வேலை செய்தும், அது மீண்டும் மீண்டும் API அழைப்புகளை ஏற்படுத்தியது
கேச் பழுதாகவில்லை.
இருப்பினும், ஒரே பயனர் பெயருக்கான (username) மூன்று ஒரே நேரத்தில் வரும் கோரிக்கைகள் (concurrent requests), GitHub-ஐ மூன்று முறை அணுகின.
இது GitHub தரவை SVG பேட்ஜ்களாக (badges) மாற்றும் ஒரு Next.js API ஆன CommitPulse-இல் நடந்தது. ஒரு README வைரலாகும் போது, ஆயிரக்கணக்கான மக்கள் ஒரே நேரத்தில் அந்த பேட்ஜைப் பார்க்கிறார்கள். இது மிகப்பெரிய போக்குவரத்துத் தேக்கத்தை (massive traffic) உருவாக்குகிறது.
வரிசைமுறை கோரிக்கைகளுக்கு (sequential requests) கேச் சரியாக வேலை செய்தது. ஆனால் ஒரே நேரத்தில் வரும் கோரிக்கைகளுக்கு (concurrent requests) அது தோல்வியடைந்தது.
பிரச்சனை இதோ:
- கோரிக்கை A கேச்-ஐச் சரிபார்க்கிறது. அது காலியாக உள்ளது (cache miss). கோரிக்கை A GitHub-லிருந்து தரவை எடுக்கத் தொடங்குகிறது.
- 5ms கழித்து கோரிக்கை B வருகிறது. அது கேச்-ஐச் சரிபார்க்கிறது. கோரிக்கை A இன்னும் முடிவடையாததால், அதுவும் காலியாகவே உள்ளது. கோரிக்கை B இரண்டாவது முறை தரவை எடுக்கத் தொடங்குகிறது.
- 10ms கழித்து கோரிக்கை C வருகிறது. அதுவும் கேச் காலியாக இருப்பதைப் பார்த்து மூன்றாவது முறை தரவை எடுக்கத் தொடங்குகிறது.
இதுதான் 'thundering herd' பிரச்சனை. அதிகப்படியான சுமையின் போது (high load), கேச் காலியாக இருப்பது உங்கள் upstream provider-க்கு ஒரே மாதிரியான அழைப்புகளின் வெள்ளத்தை ஏற்படுத்தும். நீங்கள் GitHub போன்ற வரம்புகள் கொண்ட (rate-limited) API-யைப் பயன்படுத்தினால், இது உங்கள் வரம்புகளை உடனடியாகத் தீர்த்துவிடும்.
இதற்கான தீர்வு 'request coalescing' ஆகும்.
முடிவடைந்த கேச் பதிவுகளிலிருந்து (completed cache entries), நிலுவையில் உள்ள கோரிக்கைகளை (pending requests) நீங்கள் தனித்தனியாகக் கண்காணிக்க வேண்டும். இதை நிர்வகிக்க நான் ஒரு in-flight Map-ஐ உருவாக்கினேன்:
- ஒரு கோரிக்கை தொடங்கும் போது, அதன்
Promise-ஐ ஒருMap-இல் சேமிக்கவும். - அதே சாவிக்காக (key) இரண்டாவது கோரிக்கை வந்தால், புதிய fetch-ஐத் தொடங்க வேண்டாம்.
- அதற்குப் பதிலாக,
Map-இல் உள்ள ஏற்கனவே இருக்கும்Promise-ஐத் திருப்பி அனுப்பவும். - கோரிக்கை முடிந்ததும், அதை
Map-லிருந்து நீக்கிவிட்டு, முடிவை கேச்-இல் சேமிக்கவும்.
இதன் மூலம், எத்தனை பேர் ஒரே நேரத்தில் ஒரே தரவைக் கேட்டாலும், ஒரே ஒரு அழைப்பு மட்டுமே API-ஐச் சென்றடையும் என்பது உறுதி செய்யப்படுகிறது.
இதைச் சரிசெய்யும் போது, அதே கோப்பில் இருந்த மற்ற மூன்று விளிம்புநிலை பிழைகளையும் (edge-case bugs) நான் சரிசெய்தேன்:
- விடுபட்ட டோக்கன் பிழைகள் (Missing Token Errors): சிஸ்டம் "undefined" என்பதை ஒரு சான்றாக (credential) அனுப்பியது. கோரிக்கைகளைச் செய்வதற்கு முன் டோக்கன்களைச் சரிபார்க்கும் வகையில் நான் அதை மாற்றியமைத்தேன்.
- மெமரி கசிவுகள் (Memory Leaks): Retry லாஜிக்,
AbortSignals-இல் பழைய நிகழ்வு கேட்பாளர்களை (stale event listeners) விட்டுச் சென்றது. கசிவைத் தடுக்க நான் cleanup லாஜிக்கைச் சேர்த்தேன். - URL இன்ஜெக்ஷன் (URL Injection): சிறப்பு எழுத்துக்களைக் கொண்ட பயனர் பெயர்கள் API பாதைகளை (paths) உடைத்தன. URL கட்டமைப்பைப் பாதுகாக்க நான் encoding முறையைச் சேர்த்தேன்.
ஒரு கேச் மட்டும் போதாது. தற்போது நிலுவையில் உள்ள (in flight) கோரிக்கைகளைத் தனித்துவமாக்க (deduplicate) வேண்டியது அவசியம்.
ஆதாரம்: https://dev.to/eshaanagrawal/the-cache-was-working-and-still-causing-duplicate-api-calls-3n51
