Skip to content

Commit

Permalink
Refactor: keep only a limited number of cache key mutexes (#1237)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmercm authored Jul 25, 2024
1 parent c114188 commit e7c43e5
Showing 1 changed file with 20 additions and 0 deletions.
20 changes: 20 additions & 0 deletions src/types/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ export interface CacheProps {
export default class Cache<V> {
private static readonly BUFFER_ENCODING: BufferEncoding = 'binary';

private static readonly KEY_MUTEXES_MAX_COUNT = 1000;

private keyOrder: Set<string> = new Set();

private keyValues = new Map<string, V>();

private readonly keyMutexes = new Map<string, Mutex>();

private keyMutexesLru: Set<string> = new Set();

private readonly keyMutexesMutex = new Mutex();

private hasChanged: boolean = false;
Expand Down Expand Up @@ -147,6 +151,7 @@ export default class Cache<V> {
this.keyOrder.delete(key);
this.keyValues.delete(key);
this.keyMutexes.delete(key);
this.keyMutexesLru.delete(key);
this.saveWithTimeout();
}

Expand All @@ -155,7 +160,22 @@ export default class Cache<V> {
const keyMutex = await this.keyMutexesMutex.runExclusive(() => {
if (!this.keyMutexes.has(key)) {
this.keyMutexes.set(key, new Mutex());
this.keyMutexesLru = new Set([key, ...this.keyMutexesLru]);

// Expire least recently used keys
[...this.keyMutexesLru]
.filter((lruKey) => !this.keyMutexes.get(lruKey)?.isLocked())
.slice(Cache.KEY_MUTEXES_MAX_COUNT)
.forEach((lruKey) => {
this.keyMutexes.delete(lruKey);
this.keyMutexesLru.delete(lruKey);
});
}

// Mark this key as recently used
this.keyMutexesLru.delete(key);
this.keyMutexesLru = new Set([key, ...this.keyMutexesLru]);

return this.keyMutexes.get(key) as Mutex;
});

Expand Down

0 comments on commit e7c43e5

Please sign in to comment.