isaacs / node-lru-cache

A fast cache that automatically deletes the least recently used items
http://isaacs.github.io/node-lru-cache/
ISC License
5.38k stars 353 forks source link

Dispose not called on the last stale item in a cache with purgeStale or clear #203

Closed mkomaiha closed 2 years ago

mkomaiha commented 2 years ago

Clear function gets called in purgeStale when the size of the cache is 1 and the clear dispose only loops rIndexes when disposing so stale items are not disposed. How can I handle the clean up of the last item in the cache if it is stale?

https://github.com/isaacs/node-lru-cache/blob/da932f7daaa4b013d917dd215ba18253cef56c33/index.js#L543-L553

const LRU = require("lru-cache");
const LRU_OPTIONS = {
  max: 10000,
  ttl: 1000 * 5, // 5 sec ttl
  dispose: (val, key) => {
    console.log("DISPOSE ME", key);
  },
  disposeAfter: (val, key) => {
    console.log("DISPOSE after", key);
  },
};
const LRU_CACHE = new LRU(LRU_OPTIONS);
console.log("Setting TEST");
LRU_CACHE.set("TEST", { msg: "test" });

setTimeout(() => {
  console.log("Ending program");
  LRU_CACHE.clear();
}, 1000 * 10); // Keep program alive for 10 seconds

// Output from code:
// Setting TEST
// Ending program

// Output expected code:
// Setting TEST
// DISPOSE ME TEST
// DISPOSE after TEST
// Ending program
isaacs commented 2 years ago

Ahhhh, yeah, good bug, thanks for tracking the root cause so clearly.

clear() should call dispose on all items, not just those iterated over by rindexes.

Really, it should be for (const index of this.rindexes({ allowStale: true })) and rindexes and indexes should respect that flag if provided.