diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d08b31da..fce6fa5d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] ### Added +- Change LRUDiskCache to allow subclasses to override functionality - Create new optional request option for customizing local cache behavior - Allow passing request config to VBase's getJSON method diff --git a/src/caches/LRUDiskCache.ts b/src/caches/LRUDiskCache.ts index 63ae7fd79..c55873066 100644 --- a/src/caches/LRUDiskCache.ts +++ b/src/caches/LRUDiskCache.ts @@ -5,14 +5,17 @@ import { outputJSON, readJSON, remove } from 'fs-extra' import LRU from 'lru-cache' import { join } from 'path' import ReadWriteLock from 'rwlock' +import { LocalCacheOptions } from '../HttpClient' + +export type LRUData = Record & { timeOfDeath: number } export class LRUDiskCache implements CacheLayer{ + protected disposed: number + protected hits = 0 + protected total = 0 private lock: ReadWriteLock - private disposed: number - private hits = 0 - private total = 0 - private lruStorage: LRU + private lruStorage: LRU private keyToBeDeleted: string constructor(private cachePath: string, options: LRUDiskCacheOptions, private readFile=readJSON, private writeFile=outputJSON) { @@ -33,11 +36,13 @@ export class LRUDiskCache implements CacheLayer{ noDisposeOnSet: true, } - this.lruStorage = new LRU(lruOptions) + this.lruStorage = new LRU(lruOptions) } - public has = (key: string): boolean => this.lruStorage.has(key) + public has (key: string): boolean { + return this.lruStorage.has(key) + } public getStats = (name='disk-lru-cache'): LRUStats => { const stats = { @@ -56,10 +61,10 @@ export class LRUDiskCache implements CacheLayer{ return stats } - public get = async (key: string): Promise => { - const timeOfDeath = this.lruStorage.get(key) + public async get (key: string): Promise { + const lruData = this.lruStorage.get(key) this.total += 1 - if (timeOfDeath === undefined) { + if (lruData === undefined) { // if it is an outdated file when stale=false if (this.keyToBeDeleted) { @@ -85,7 +90,7 @@ export class LRUDiskCache implements CacheLayer{ }) // if it is an outdated file when stale=true - if (timeOfDeath < Date.now()) { + if (lruData.timeOfDeath < Date.now()) { this.lruStorage.del(key) await this.deleteFile(key) } @@ -93,15 +98,10 @@ export class LRUDiskCache implements CacheLayer{ return data } - public set = async (key: string, value: V, maxAge?: number): Promise => { - let timeOfDeath = NaN - if (maxAge) { - timeOfDeath = maxAge + Date.now() - this.lruStorage.set(key, timeOfDeath, maxAge) - } - else { - this.lruStorage.set(key, NaN) - } + public async set (key: string, value: V, maxAge?: number, localCacheOptions?: LocalCacheOptions): Promise { + const timeOfDeath = maxAge ? maxAge + Date.now() : NaN + const lruData = this.buildLRUData(timeOfDeath, localCacheOptions) + this.lruStorage.set(key, lruData, maxAge ? maxAge : undefined) if (this.keyToBeDeleted && this.keyToBeDeleted !== key) { await this.deleteFile(this.keyToBeDeleted) @@ -124,6 +124,19 @@ export class LRUDiskCache implements CacheLayer{ return !failure } + /** + * Builds the data object that will be stored at the LRU memory storage. + * Subclasses that need to store more than just the time of death should + * override this. + */ + protected buildLRUData(timeOfDeath: number, localCacheOptions?: LocalCacheOptions): LRUData { + return { timeOfDeath } + } + + protected getLRU() { + return this.lruStorage + } + private getPathKey = (key: string): string => { return join(this.cachePath, key) }