La caché funcionaba, pero aun así causaba llamadas duplicadas a la API
La caché no estaba rota.
Sin embargo, tres solicitudes concurrentes para el mismo nombre de usuario impactaron GitHub tres veces.
Esto sucedió en CommitPulse, una API de Next.js que convierte datos de GitHub en insignias SVG. Cuando un README se vuelve viral, miles de personas ven la insignia al mismo tiempo. Esto genera un tráfico masivo.
La caché funcionaba para solicitudes secuenciales. Fallaba para las concurrentes.
Aquí está el problema:
- La solicitud A comprueba la caché. Es un fallo de caché (miss). La solicitud A comienza a obtener datos de GitHub.
- La solicitud B llega 5 ms después. Comprueba la caché. Sigue siendo un fallo porque la solicitud A no ha terminado. La solicitud B inicia una segunda obtención de datos.
- La solicitud C llega 10 ms después. También detecta un fallo de caché e inicia una tercera obtención de datos.
Este es el problema de la "manada atronadora" (thundering herd). Un fallo de caché bajo una carga alta desencadena una inundación de llamadas idénticas a tu proveedor upstream. Si utilizas una API con límite de velocidad (rate-limited) como GitHub, esto puede agotar tus límites instantáneamente.
La solución es la coalescencia de solicitudes (request coalescing).
Debes rastrear las solicitudes pendientes por separado de las entradas de caché completadas. Implementé un Map para gestionar las solicitudes en curso (in-flight):
- Cuando una solicitud comienza, almacena su
Promiseen unMap. - Si llega una segunda solicitud para la misma clave, no inicies una nueva obtención de datos.
- En su lugar, devuelve la
Promiseexistente delMap. - Una vez que la solicitud finaliza, elimínala del
Mapy guarda el resultado en la caché.
Esto garantiza que, sin importar cuántas personas soliciten los mismos datos a la vez, solo una llamada impacte la API.
Mientras solucionaba esto, también resolví otros tres errores de casos límite en el mismo archivo:
- Errores de token faltante: El sistema enviaba "undefined" como credencial. Lo actualicé para validar los tokens antes de realizar las solicitudes.
- Fugas de memoria (Memory Leaks): La lógica de reintento dejaba escuchadores de eventos obsoletos en los
AbortSignals. Añadí lógica de limpieza para prevenir fugas. - Inyección de URL: Los nombres de usuario con caracteres especiales rompían las rutas de la API. Añadí codificación para proteger la estructura de la URL.
Una caché no es suficiente. También necesitas deduplicar las solicitudes que están actualmente en curso.
Fuente: https://dev.to/eshaanagrawal/the-cache-was-working-and-still-causing-duplicate-api-calls-3n51
