کیش کام کر رہا تھا، لیکن پھر بھی اس کی وجہ سے API کالز ڈپلیکیٹ ہو رہی تھیں
کیش خراب نہیں تھا۔
اس کے باوجود، ایک ہی یوزر نیم کے لیے تین بیک وقت (concurrent) آنے والی درخواستوں نے GitHub کو تین بار ہٹ کیا۔
یہ CommitPulse میں ہوا، جو کہ ایک Next.js API ہے جو GitHub ڈیٹا کو SVG بیجز میں تبدیل کرتی ہے۔ جب کوئی README وائرل ہو جاتا ہے، تو ہزاروں لوگ ایک ساتھ بیج دیکھتے ہیں۔ اس سے ٹریفک میں بہت زیادہ اضافہ ہو جاتا ہے۔
کیش ترتیب وار (sequential) درخواستوں کے لیے کام کر رہا تھا۔ لیکن بیک وقت (concurrent) آنے والی درخواستوں کے لیے یہ ناکام رہا۔
مسئلہ یہ ہے:
- درخواست A کیش چیک کرتی ہے۔ یہ 'miss' ہے۔ درخواست A GitHub سے ڈیٹا حاصل کرنا شروع کر دیتی ہے۔
- درخواست B 5ms بعد آتی ہے۔ یہ کیش چیک کرتی ہے۔ یہ اب بھی 'miss' ہے کیونکہ درخواست A ابھی مکمل نہیں ہوئی۔ درخواست B دوسری fetch شروع کر دیتی ہے۔
- درخواست C 10ms بعد آتی ہے۔ یہ بھی کیش مس (cache miss) دیکھتی ہے اور تیسری fetch شروع کر دیتی ہے۔
یہ thundering herd کا مسئلہ ہے۔ زیادہ لوڈ کے دوران کیش مس (cache miss) ہونے سے آپ کے اپ اسٹریم فراہم کنندہ (upstream provider) کو ایک جیسی کالز کا سیلاب آ جاتا ہے۔ اگر آپ GitHub جیسی ریٹ لمیٹڈ (rate-limited) API استعمال کر رہے ہیں، تو یہ فوری طور پر آپ کی حد (limits) ختم کر سکتا ہے۔
اس کا حل request coalescing ہے۔
آپ کو مکمل شدہ کیش انٹریز سے الگ، زیر التوا (pending) درخواستوں کو ٹریک کرنا ہوگا۔ میں نے اسے مینیج کرنے کے لیے ایک in-flight Map کا استعمال کیا:
- جب کوئی درخواست شروع ہو، تو اس کے Promise کو ایک Map میں محفوظ کریں۔
- اگر اسی کی (key) کے لیے دوسری درخواست آئے، تو نئی fetch شروع نہ کریں۔
- اس کے بجائے، Map سے موجودہ Promise واپس کر دیں۔
- جب درخواست مکمل ہو جائے، تو اسے Map سے ہٹا دیں اور نتیجہ کیش میں محفوظ کر لیں۔
یہ اس بات کو یقینی بناتا ہے کہ چاہے کتنے ہی لوگ ایک ساتھ ایک ہی ڈیٹا کی درخواست کریں، API کو صرف ایک ہی کال جائے گی۔
اسے ٹھیک کرتے ہوئے، میں نے اسی فائل میں تین دیگر edge-case بگ بھی حل کیے:
- Missing Token Errors: سسٹم نے بطور کریڈنشل (credential) "undefined" بھیجا۔ میں نے درخواستیں بھیجنے سے پہلے ٹوکنز کی تصدیق (validate) کرنے کے لیے اسے اپ ڈیٹ کیا۔
- Memory Leaks: ری ٹرائی لاجک (retry logic) نے AbortSignals پر پرانے ایونٹ لسنرز (event listeners) چھوڑ دیے۔ میں نے لیکس کو روکنے کے لیے کلین اپ لاجک (cleanup logic) شامل کی۔
- URL Injection: خصوصی حروف (special characters) والے یوزر نیمز نے API پاتھ کو خراب کر دیا۔ میں نے URL کے ڈھانچے کو محفوظ بنانے کے لیے انکوڈنگ (encoding) کا اضافہ کیا۔
صرف کیش کافی نہیں ہے۔ آپ کو ان درخواستوں کو بھی deduplicate کرنے کی ضرورت ہے جو اس وقت in flight ہیں۔
Source: https://dev.to/eshaanagrawal/the-cache-was-working-and-still-causing-duplicate-api-calls-3n51
