import * as plugins from './levelcache.plugins'; import { CacheDiskManager } from './levelcache.classes.cache.diskmanager'; import { CacheMemoryManager } from './levelcache.classes.cache.memorymanager'; import { CacheS3Manager } from './levelcache.classes.cache.s3manager'; import { CacheEntry } from './levelcache.classes.cacheentry'; import { CacheRouter } from './levelcache.classes.cacherouter'; import { AbstractCache } from './levelcache.abstract.classes.cache'; export interface ILevelCacheConstructorOptions { /** * a unique id when having more than one cache */ cacheId: string; maxMemoryStorageInMB?: number; maxDiskStorageInMB?: number; maxS3StorageInMB?: number; diskStoragePath?: string; s3Config?: plugins.smartbucket.ISmartBucketConfig; s3BucketName?: string; forceLevel?: 'memory' | 'disk' | 's3'; expirationInMs?: number; immutableCache?: boolean; persistentCache?: boolean; } /** * a leveled cache for storing things for a short time */ export class LevelCache extends AbstractCache { private readyDeferred = plugins.smartpromise.defer(); public ready = this.readyDeferred.promise; public status: 'active' = 'active'; // artifact of AbstractCache public cacheRouter = new CacheRouter(this); public cacheDiskManager: CacheDiskManager; public cacheMemoryManager: CacheMemoryManager; public cacheS3Manager: CacheS3Manager; public options: ILevelCacheConstructorOptions; constructor(optionsArg: ILevelCacheConstructorOptions) { super(); this.options = optionsArg; this.init(); } public async init() { this.cacheDiskManager = new CacheDiskManager(this); this.cacheMemoryManager = new CacheMemoryManager(this); this.cacheS3Manager = new CacheS3Manager(this); await Promise.all([ this.cacheDiskManager.ready, this.cacheMemoryManager.ready, this.cacheS3Manager.ready, ]); this.readyDeferred.resolve(); } // store things public async storeCacheEntryByKey(keyArg: string, cacheEntryArg: CacheEntry): Promise { cacheEntryArg.key = keyArg; const targetCache = await this.cacheRouter.getCacheForStoreAction(keyArg, cacheEntryArg); await targetCache.storeCacheEntryByKey(keyArg, cacheEntryArg); } // retrieve things /** * retrieve cache entry */ public async retrieveCacheEntryByKey(keyArg: string): Promise { const targetCache = await this.cacheRouter.getCacheForRetrieveAction(keyArg); if (targetCache) { const cacheEntry = await targetCache.retrieveCacheEntryByKey(keyArg); return cacheEntry; } else { return null; } } public async checkKeyPresence(keyArg: string): Promise { return plugins.smartpromise.getFirstTrueOrFalse([ this.cacheMemoryManager.checkKeyPresence(keyArg), this.cacheDiskManager.checkKeyPresence(keyArg), this.cacheS3Manager.checkKeyPresence(keyArg) ]); } // cache maintenance /** * cleans the cache */ public async clean(): Promise { await Promise.all([ this.cacheDiskManager.clean(), this.cacheDiskManager.clean(), this.cacheS3Manager.clean(), ]); } }