Cache Berfungsi, Tetapi Ia Masih Menyebabkan Panggilan API Berulang

Cache tersebut tidak rosak.

Namun, tiga permintaan serentak untuk nama pengguna yang sama telah memanggil GitHub sebanyak tiga kali.

Ini berlaku dalam CommitPulse, sebuah API Next.js yang menukarkan data GitHub kepada lencana SVG. Apabila sebuah README menjadi tular, beribu-ribu orang akan melihat lencana tersebut pada masa yang sama. Ini mewujudkan trafik yang sangat besar.

Cache berfungsi untuk permintaan berturutan. Ia gagal untuk permintaan serentak.

Inilah masalahnya:

  • Permintaan A menyemak cache. Ia adalah cache miss. Permintaan A mula mengambil data daripada GitHub.
  • Permintaan B tiba 5ms kemudian. Ia menyemak cache. Ia masih merupakan cache miss kerana Permintaan A belum selesai. Permintaan B memulakan pengambilan data kedua.
  • Permintaan C tiba 10ms kemudian. Ia juga melihat cache miss dan memulakan pengambilan data ketiga.

Ini adalah masalah thundering herd. Cache miss di bawah beban tinggi mencetuskan lambakan panggilan serupa kepada pembekal upstream anda. Jika anda menggunakan API yang mempunyai had kadar (rate-limited) seperti GitHub, ini boleh menghabiskan had anda dengan serta-merta.

Penyelesaiannya ialah request coalescing.

Anda mesti menjejaki permintaan yang sedang menunggu secara berasingan daripada entri cache yang telah selesai. Saya melaksanakan satu Map in-flight untuk menguruskan perkara ini:

  • Apabila permintaan bermula, simpan Promise tersebut di dalam satu Map.
  • Jika permintaan kedua tiba untuk kunci yang sama, jangan mulakan pengambilan data baharu.
  • Sebaliknya, pulangkan Promise sedia ada daripada Map tersebut.
  • Sebaik sahaja permintaan selesai, buangkannya daripada Map dan simpan hasilnya ke dalam cache.

Ini memastikan tidak kira berapa ramai orang meminta data yang sama pada satu masa, hanya satu panggilan sahaja yang akan memanggil API tersebut.

Sambil membaiki perkara ini, saya juga menyelesaikan tiga pepijat kes terpinggir (edge-case) yang lain dalam fail yang sama:

  • Ralat Token Hilang: Sistem menghantar "undefined" sebagai kredential. Saya telah mengemas kininya untuk mengesahkan token sebelum membuat permintaan.
  • Kebocoran Memori (Memory Leaks): Logik cubaan semula (retry) meninggalkan pendengar acara (event listeners) yang usang pada AbortSignals. Saya telah menambah logik pembersihan untuk mengelakkan kebocoran.
  • Suntikan URL (URL Injection): Nama pengguna dengan aksara khas merosakkan laluan API. Saya telah menambah pengekodan (encoding) untuk melindungi struktur URL.

Cache sahaja tidak mencukupi. Anda juga perlu menghapuskan duplikasi (deduplicate) terhadap permintaan yang sedang dalam proses (in flight).

Sumber: https://dev.to/eshaanagrawal/the-cache-was-working-and-still-causing-duplicate-api-calls-3n51