كانت الذاكرة المخبئية تعمل، ومع ذلك تسببت في استدعاءات مكررة لواجهة برمجة التطبيقات (API)
لم تكن الذاكرة المخبئية معطلة.
ومع ذلك، أدت ثلاثة طلبات متزامنة لنفس اسم المستخدم إلى استدعاء GitHub ثلاث مرات.
حدث هذا في CommitPulse، وهي واجهة برمجة تطبيقات (API) مبنية على Next.js تقوم بتحويل بيانات GitHub إلى شارات SVG. عندما ينتشر ملف README بشكل واسع، يشاهد آلاف الأشخاص الشارة في وقت واحد، مما يؤدي إلى حركة مرور هائلة.
كانت الذاكرة المخبئية تعمل مع الطلبات المتتالية، لكنها فشلت مع الطلبات المتزامنة.
إليكم المشكلة:
- الطلب A يفحص الذاكرة المخبئية. النتيجة هي "عدم وجود بيانات" (miss). يبدأ الطلب A بجلب البيانات من GitHub.
- يصل الطلب B بعد 5 مللي ثانية. يفحص الذاكرة المخبئية، ولا يزال لا يجد بيانات لأن الطلب A لم ينتهِ بعد. يبدأ الطلب B عملية جلب ثانية.
- يصل الطلب C بعد 10 مللي ثانية. يرى أيضاً عدم وجود بيانات في الذاكرة المخبئية ويبدأ عملية جلب ثالثة.
هذه هي مشكلة "القطيع الهائج" (thundering herd problem). حيث يؤدي عدم وجود بيانات في الذاكرة المخبئية تحت ضغط عالٍ إلى إطلاق سيل من الاستدعاءات المتطابقة لمزود الخدمة الخاص بك. إذا كنت تستخدم واجهة برمجة تطبيقات محدودة المعدل (rate-limited) مثل GitHub، فقد يؤدي ذلك إلى استنفاد حدود الاستخدام الخاصة بك فوراً.
الحل هو "دمج الطلبات" (request coalescing).
يجب عليك تتبع الطلبات المعلقة بشكل منفصل عن مدخلات الذاكرة المخبئية المكتملة. لقد قمت بتنفيذ Map للطلبات قيد التنفيذ (in-flight) لإدارة ذلك:
- عند بدء طلب ما، قم بتخزين الـ
Promiseالخاص به فيMap. - إذا وصل طلب ثانٍ لنفس المفتاح، فلا تبدأ عملية جلب جديدة.
- بدلاً من ذلك، قم بإرجاع الـ
Promiseالموجود في الـMap. - بمجرد انتهاء الطلب، قم بإزالته من الـ
Mapواحفظ النتيجة في الذاكرة المخبئية.
يضمن ذلك أنه بغض النظر عن عدد الأشخاص الذين يطلبون نفس البيانات في وقت واحد، سيتم إجراء استدعاء واحد فقط لواجهة برمجة التطبيقات.
أثناء إصلاح هذه المشكلة، قمت أيضاً بحل ثلاث ثغرات برمجية أخرى في حالات حافة (edge-case) في الملف نفسه:
- أخطاء الرموز المفقودة (Missing Token Errors): كان النظام يرسل "undefined" كبيانات اعتماد. قمت بتحديثه للتحقق من صحة الرموز (tokens) قبل إجراء الطلبات.
- تسريبات الذاكرة (Memory Leaks): تركت منطق إعادة المحاولة مستمعي أحداث (event listeners) قديمة على
AbortSignals. أضفت منطق تنظيف لمنع التسريبات. - حقن الروابط (URL Injection): تسببت أسماء المستخدمين التي تحتوي على رموز خاصة في كسر مسارات واجهة برمجة التطبيقات. أضفت عملية ترميز (encoding) لحماية بنية الـ URL.
الذاكرة المخبئية ليست كافية. أنت بحاجة أيضاً إلى إزالة تكرار الطلبات التي هي قيد التنفيذ حالياً.
المصدر: https://dev.to/eshaanagrawal/the-cache-was-working-and-still-causing-duplicate-api-calls-3n51
