Ghost/ghost/event-aware-cache-wrapper/lib/event-aware-cache-wrapper.js
Naz f74b19ab61
Added implementation for event-aware cache
refs https://github.com/TryGhost/Toolbox/issues/522

- The main feature of this cache wrapper is being able to "reset" the the cache without calling the "reset" on the wrapped cache. Being able to invalidate caches without accessing the data is a feature needed to run on caches with shared environment.
- Cache invalidation happens through a special "reset time" key being added to each key when setting or getting a value, when the cache is reset the reset time is set to a new value - essentially invalidating all previously accessible values.
2023-02-23 13:07:04 +08:00

53 lines
1.4 KiB
JavaScript

class EventAwareCacheWrapper {
#cache;
#lastReset;
/**
* @param {Object} deps
* @param {Object} deps.cache - cache instance extending adapter-base-cache
* @param {Object} [deps.eventRegistry] - event registry instance
* @param {Number} [deps.lastReset] - timestamp of last reset
* @param {String[]} [deps.resetEvents] - event to listen to triggering reset
*/
constructor(deps) {
this.#cache = deps.cache;
this.#lastReset = deps.lastReset || Date.now();
if (deps.resetEvents && deps.eventRegistry) {
this.#initListeners(deps.eventRegistry, deps.resetEvents);
}
}
#initListeners(eventRegistry, eventsToResetOn) {
eventsToResetOn.forEach((event) => {
eventRegistry.on(event, () => {
this.reset();
});
});
}
#buildResetAwareKey(key) {
return `${this.#lastReset}:${key}`;
}
async get(key) {
return this.#cache.get(this.#buildResetAwareKey(key));
}
async set(key, value) {
return this.#cache.set(this.#buildResetAwareKey(key), value);
}
/**
* Reset the cache without removing of flushing the keys
* The mechanism is based on adding a timestamp to the key
* This way the cache is invalidated but the keys are still there
*/
reset() {
this.#lastReset = Date.now();
}
}
module.exports = EventAwareCacheWrapper;