0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-04 02:01:58 -05:00

Removed synthetic timestamp-based cache resets

refs https://github.com/TryGhost/Arch/issues/5

- Current event-aware cache wrapper has been using a timestamp as a way to create keys in Redis cache and reset them all at once. We are now moving on to the updated Redis adapter that supports "reset()" natively, so there's no need for synthetic resets.
This commit is contained in:
Naz 2023-08-09 14:33:15 +08:00 committed by naz
parent b60d5bbe06
commit 5ab81554fc
2 changed files with 6 additions and 32 deletions
ghost/event-aware-cache-wrapper

View file

@ -1,18 +1,13 @@
class EventAwareCacheWrapper { class EventAwareCacheWrapper {
#cache; #cache;
#lastReset;
/** /**
* @param {Object} deps * @param {Object} deps
* @param {Object} deps.cache - cache instance extending adapter-base-cache * @param {Object} deps.cache - cache instance extending adapter-base-cache
* @param {Object} [deps.eventRegistry] - event registry instance * @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 * @param {String[]} [deps.resetEvents] - event to listen to triggering reset
*/ */
constructor(deps) { constructor(deps) {
this.#cache = deps.cache; this.#cache = deps.cache;
this.#lastReset = deps.lastReset || Date.now();
if (deps.resetEvents && deps.eventRegistry) { if (deps.resetEvents && deps.eventRegistry) {
this.#initListeners(deps.eventRegistry, deps.resetEvents); this.#initListeners(deps.eventRegistry, deps.resetEvents);
@ -27,25 +22,16 @@ class EventAwareCacheWrapper {
}); });
} }
#buildResetAwareKey(key) {
return `${this.#lastReset}:${key}`;
}
async get(key) { async get(key) {
return this.#cache.get(this.#buildResetAwareKey(key)); return this.#cache.get(key);
} }
async set(key, value) { async set(key, value) {
return this.#cache.set(this.#buildResetAwareKey(key), value); return this.#cache.set(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() { reset() {
this.#lastReset = Date.now(); return this.#cache.reset();
} }
} }

View file

@ -4,12 +4,6 @@ const InMemoryCache = require('@tryghost/adapter-cache-memory-ttl');
const EventAwareCacheWrapper = require('../index'); const EventAwareCacheWrapper = require('../index');
const {EventEmitter} = require('stream'); const {EventEmitter} = require('stream');
const sleep = ms => (
new Promise((resolve) => {
setTimeout(resolve, ms);
})
);
describe('EventAwareCacheWrapper', function () { describe('EventAwareCacheWrapper', function () {
it('Can initialize', function () { it('Can initialize', function () {
const cache = new InMemoryCache(); const cache = new InMemoryCache();
@ -22,26 +16,23 @@ describe('EventAwareCacheWrapper', function () {
describe('get', function () { describe('get', function () {
it('calls a wrapped cache with extra key', async function () { it('calls a wrapped cache with extra key', async function () {
const cache = new InMemoryCache(); const cache = new InMemoryCache();
const lastReset = Date.now();
const wrapper = new EventAwareCacheWrapper({ const wrapper = new EventAwareCacheWrapper({
cache: cache, cache: cache
lastReset: lastReset
}); });
await wrapper.set('a', 'b'); await wrapper.set('a', 'b');
assert.equal(await wrapper.get('a'), 'b'); assert.equal(await wrapper.get('a'), 'b');
assert.equal(await cache.get(`${lastReset}:a`), 'b'); assert.equal(await cache.get('a'), 'b');
}); });
}); });
describe('listens to reset events', function () { describe('listens to reset events', function () {
it('resets the cache when reset event is triggered', async function () { it('resets the cache when reset event is triggered', async function () {
const cache = new InMemoryCache(); const cache = new InMemoryCache();
const lastReset = Date.now();
const eventRegistry = new EventEmitter(); const eventRegistry = new EventEmitter();
const wrapper = new EventAwareCacheWrapper({ const wrapper = new EventAwareCacheWrapper({
cache: cache, cache: cache,
lastReset: lastReset,
resetEvents: ['site.changed'], resetEvents: ['site.changed'],
eventRegistry: eventRegistry eventRegistry: eventRegistry
}); });
@ -49,9 +40,6 @@ describe('EventAwareCacheWrapper', function () {
await wrapper.set('a', 'b'); await wrapper.set('a', 'b');
assert.equal(await wrapper.get('a'), 'b'); assert.equal(await wrapper.get('a'), 'b');
// let the time tick to get new lastReset
await sleep(100);
eventRegistry.emit('site.changed'); eventRegistry.emit('site.changed');
assert.equal(await wrapper.get('a'), undefined); assert.equal(await wrapper.get('a'), undefined);