క్యాష్ పని చేస్తోంది, కానీ అది ఇంకా డూప్లికేట్ API కాల్స్కు కారణమవుతోంది
క్యాష్ పాడైపోలేదు.
అయినప్పటికీ, ఒకే యూజర్ నేమ్ కోసం వచ్చిన మూడు కన్కరెంట్ రిక్వెస్ట్లు GitHubని మూడుసార్లు హిట్ చేశాయి.
ఇది CommitPulseలో జరిగింది, ఇది GitHub డేటాను SVG బ్యాడ్జ్లుగా మార్చే ఒక Next.js API. ఒక README వైరల్ అయినప్పుడు, వేలాది మంది ఒకేసారి ఆ బ్యాడ్జ్ని చూస్తారు. దీనివల్ల భారీ ట్రాఫిక్ ఏర్పడుతుంది.
క్యాష్ సీక్వెన్షియల్ రిక్వెస్ట్లకు సరిగ్గా పనిచేసింది. కానీ కన్కరెంట్ రిక్వెస్ట్లకు మాత్రం విఫలమైంది.
సమస్య ఇక్కడ ఉంది:
- రిక్వెస్ట్ A క్యాష్ను తనిఖీ చేస్తుంది. అది మిస్ (miss) అయింది. రిక్వెస్ట్ A GitHub నుండి డేటాను పొందడం (fetching) ప్రారంభిస్తుంది.
- 5ms తర్వాత రిక్వెస్ట్ B వస్తుంది. అది క్యాష్ను తనిఖీ చేస్తుంది. రిక్వెస్ట్ A ఇంకా పూర్తి కాలేదు కాబట్టి, ఇది కూడా మిస్ అవుతుంది. రిక్వెస్ట్ B రెండవ ఫెచ్ ప్రారంభిస్తుంది.
- 10ms తర్వాత రిక్వెస్ట్ C వస్తుంది. ఇది కూడా క్యాష్ మిస్ను చూసి మూడవ ఫెచ్ ప్రారంభిస్తుంది.
ఇది 'thundering herd' సమస్య. అధిక లోడ్ ఉన్నప్పుడు క్యాష్ మిస్ అవ్వడం వల్ల మీ అప్స్ట్రీమ్ ప్రొవైడర్కు ఒకే రకమైన కాల్స్ వరదలా వస్తాయి. మీరు GitHub వంటి రేట్-లిమిటెడ్ (rate-limited) APIని ఉపయోగిస్తుంటే, ఇది మీ లిమిట్లను తక్షణమే అయిపోయేలా చేస్తుంది.
దీనికి పరిష్కారం 'request coalescing'.
పూర్తయిన క్యాష్ ఎంట్రీల నుండి వేచి ఉన్న (pending) రిక్వెస్ట్లను మీరు విడిగా ట్రాక్ చేయాలి. దీనిని నిర్వహించడానికి నేను ఒక in-flight Mapని ఇంప్లిమెంట్ చేశాను:
- రిక్వెస్ట్ ప్రారంభమైనప్పుడు, దాని Promiseని ఒక Mapలో స్టోర్ చేయండి.
- ఒకవేళ అదే కీ కోసం రెండవ రిక్వెస్ట్ వస్తే, కొత్త ఫెచ్ ప్రారంభించవద్దు.
- దానికి బదులుగా, Map నుండి ఉన్న Promiseని తిరిగి ఇవ్వండి.
- రిక్వెస్ట్ పూర్తయిన తర్వాత, దానిని Map నుండి తొలగించి, ఫలితాన్ని క్యాష్లో సేవ్ చేయండి.
దీనివల్ల ఎంతమంది ఒకేసారి ఒకే డేటా కోసం రిక్వెస్ట్ చేసినా, కేవలం ఒకే ఒక్క కాల్ APIని హిట్ చేస్తుంది.
దీనిని పరిష్కరించే క్రమంలో, అదే ఫైల్లో ఉన్న ఇతర మూడు ఎడ్జ్-కేస్ (edge-case) బగ్లను కూడా నేను పరిష్కరించాను:
- మిస్సింగ్ టోకెన్ ఎర్రర్స్ (Missing Token Errors): సిస్టమ్ క్రెడెన్షియల్గా "undefined"ని పంపింది. రిక్వెస్ట్లు చేసే ముందు టోకెన్లను వాలిడేట్ చేసేలా నేను అప్డేట్ చేశాను.
- మెమరీ లీక్స్ (Memory Leaks): రీట్రై లాజిక్ వల్ల AbortSignals పై పాత ఈవెంట్ లిజనర్లు (event listeners) మిగిలిపోయాయి. లీక్లను నివారించడానికి నేను క్లీనప్ లాజిక్ను జోడించాను.
- URL ఇంజెక్షన్ (URL Injection): స్పెషల్ క్యారెక్టర్లు ఉన్న యూజర్ నేమ్స్ API పాత్లను పాడుచేస్తున్నాయి. URL స్ట్రక్చర్ను రక్షించడానికి నేను ఎన్కోడింగ్ను (encoding) జోడించాను.
కేవలం క్యాష్ మాత్రమే సరిపోదు. ప్రస్తుతం ఇన్-ఫ్లైట్ (in flight) లో ఉన్న రిక్వెస్ట్లను కూడా మీరు డూప్లికేట్ చేయకుండా (deduplicate) చూడాలి.
మూలం: https://dev.to/eshaanagrawal/the-cache-was-working-and-still-causing-duplicate-api-calls-3n51
