0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-03-11 02:12:21 -05:00

Ensured parallel reads from cache only fetch data once

This commit is contained in:
Fabien "egg" O'Carroll 2024-01-31 17:16:27 +07:00 committed by Fabien O'Carroll
parent 071f299408
commit 670440cecd

View file

@ -82,6 +82,7 @@ class AdapterCacheRedis extends BaseCacheAdapter {
this.refreshAheadFactor = config.refreshAheadFactor || 0;
this.getTimeoutMilliseconds = config.getTimeoutMilliseconds || null;
this.currentlyExecutingBackgroundRefreshes = new Set();
this.currentlyExecutingReads = new Map();
this.keyPrefix = config.keyPrefix;
this._keysPattern = config.keyPrefix ? `${config.keyPrefix}*` : '';
this.redisClient = this.cache.store.getClient();
@ -211,7 +212,23 @@ class AdapterCacheRedis extends BaseCacheAdapter {
* @param {() => Promise<any>} [fetchData] An optional function to fetch the data, which will be used in the case of a cache MISS or a background refresh
*/
async get(key, fetchData) {
return this.#get(key, fetchData);
const internalKey = this._buildKey(key);
if (this.currentlyExecutingReads.has(internalKey)) {
return this.currentlyExecutingReads.get(internalKey).promise;
}
const deferredResult = deferred();
this.currentlyExecutingReads.set(internalKey, deferredResult);
this.#get(key, fetchData)
.then((result) => {
deferredResult.resolve(result);
this.currentlyExecutingReads.delete(key);
})
.catch((err) => {
deferredResult.reject(err);
this.currentlyExecutingReads.delete(key);
});
return deferredResult.promise;
}
async #get(key, fetchData) {