fix(caching): properly respect ttl for all cache levels
This commit is contained in:
parent
f7b6df5ff7
commit
6b57e8b1f3
18
test/test.ts
18
test/test.ts
@ -21,7 +21,23 @@ tap.test('should cache a value', async () => {
|
||||
})
|
||||
);
|
||||
const result = await testLevelCache.retrieveCacheEntryByKey('mykey');
|
||||
console.log(result);
|
||||
expect(result.contents.toString()).to.equal('heythere');
|
||||
});
|
||||
|
||||
tap.test('should respect ttl', async (tools) => {
|
||||
await testLevelCache.storeCacheEntryByKey(
|
||||
'mykey',
|
||||
new CacheEntry({
|
||||
contents: Buffer.from('heythere'),
|
||||
ttl: 1000,
|
||||
typeInfo: 'string',
|
||||
})
|
||||
);
|
||||
const result = await testLevelCache.retrieveCacheEntryByKey('mykey');
|
||||
expect(result.contents.toString()).to.equal('heythere');
|
||||
await tools.delayFor(1100);
|
||||
const result2 = await testLevelCache.retrieveCacheEntryByKey('mykey');
|
||||
expect(result2).to.be.null;
|
||||
});
|
||||
|
||||
tap.start();
|
||||
|
@ -4,22 +4,35 @@ export abstract class AbstractCache {
|
||||
public abstract ready: Promise<void>;
|
||||
public abstract status: 'active' | 'inactive';
|
||||
|
||||
// Blobs
|
||||
// Cache Entries
|
||||
/**
|
||||
* store a Blob
|
||||
*/
|
||||
public abstract storeCacheEntryByKey(keyArg: string, valueArg: CacheEntry): Promise<void>;
|
||||
|
||||
// Cache Entries
|
||||
/**
|
||||
* retrieve cache entry
|
||||
*/
|
||||
public abstract retrieveCacheEntryByKey(keyArg: string): Promise<CacheEntry>;
|
||||
|
||||
/**
|
||||
* checks for the presence of a key
|
||||
* @param keyArg
|
||||
*/
|
||||
public abstract checkKeyPresence(keyArg: string): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* cleans the cache
|
||||
* delete a key
|
||||
*/
|
||||
public abstract clean(): Promise<void>;
|
||||
public abstract deleteCacheEntryByKey(keyArg: string): Promise<void>;
|
||||
|
||||
/**
|
||||
* clean the cache
|
||||
*/
|
||||
public abstract cleanOutdated(): Promise<void>;
|
||||
|
||||
/**
|
||||
* cleans the complete cache
|
||||
*/
|
||||
public abstract cleanAll(): Promise<void>;
|
||||
}
|
||||
|
@ -51,14 +51,18 @@ export class CacheDiskManager extends AbstractCache {
|
||||
);
|
||||
}
|
||||
|
||||
public async checkKeyPresence(keyArg): Promise<boolean> {
|
||||
public async checkKeyPresence(keyArg: string): Promise<boolean> {
|
||||
return plugins.smartfile.fs.isFile(plugins.path.join(this.fsPath, encodeURIComponent(keyArg)));
|
||||
}
|
||||
|
||||
/**
|
||||
* cleans the DiskCache directory
|
||||
*/
|
||||
public async clean() {
|
||||
public async deleteCacheEntryByKey(keyArg: string) {
|
||||
await plugins.smartfile.fs.remove(plugins.path.join(this.fsPath, encodeURIComponent(keyArg)));
|
||||
}
|
||||
|
||||
|
||||
public async cleanOutdated() {}
|
||||
|
||||
public async cleanAll() {
|
||||
if (this.status === 'active') {
|
||||
if (plugins.smartfile.fs.isDirectory(this.fsPath)) {
|
||||
await plugins.smartfile.fs.ensureEmptyDir(this.fsPath);
|
||||
|
@ -38,7 +38,13 @@ export class CacheMemoryManager extends AbstractCache {
|
||||
}
|
||||
}
|
||||
|
||||
public async clean() {
|
||||
public async deleteCacheEntryByKey(keyArg: string) {
|
||||
this.fastMap.removeFromMap(keyArg);
|
||||
}
|
||||
|
||||
public async cleanOutdated() {}
|
||||
|
||||
public async cleanAll() {
|
||||
this.fastMap.clean();
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,18 @@ export class CacheS3Manager extends AbstractCache {
|
||||
return false;
|
||||
}
|
||||
|
||||
public async clean() {
|
||||
public async deleteCacheEntryByKey(keyArg: string) {
|
||||
if(this.status === 'active') {
|
||||
await this.s3CacheDir.fastRemove(encodeURIComponent(keyArg));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clean outdated
|
||||
*/
|
||||
public async cleanOutdated() {}
|
||||
|
||||
public async cleanAll() {
|
||||
await this.s3CacheDir.deleteWithAllContents();
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ export class CacheEntry
|
||||
@plugins.smartjson.foldDec()
|
||||
contents: Buffer;
|
||||
|
||||
@plugins.smartjson.foldDec()
|
||||
public createdAt: number;
|
||||
|
||||
public toStorageJsonString(): string {
|
||||
return this.foldToJson();
|
||||
}
|
||||
|
@ -62,6 +62,7 @@ export class LevelCache extends AbstractCache {
|
||||
public async storeCacheEntryByKey(keyArg: string, cacheEntryArg: CacheEntry): Promise<void> {
|
||||
cacheEntryArg.key = keyArg;
|
||||
const targetCache = await this.cacheRouter.getCacheForStoreAction(keyArg, cacheEntryArg);
|
||||
cacheEntryArg.createdAt = Date.now();
|
||||
await targetCache.storeCacheEntryByKey(keyArg, cacheEntryArg);
|
||||
}
|
||||
|
||||
@ -73,6 +74,10 @@ export class LevelCache extends AbstractCache {
|
||||
const targetCache = await this.cacheRouter.getCacheForRetrieveAction(keyArg);
|
||||
if (targetCache) {
|
||||
const cacheEntry = await targetCache.retrieveCacheEntryByKey(keyArg);
|
||||
if (cacheEntry.createdAt + cacheEntry.ttl < Date.now()) {
|
||||
await this.deleteCacheEntryByKey(keyArg).catch();
|
||||
return null;
|
||||
}
|
||||
return cacheEntry;
|
||||
} else {
|
||||
return null;
|
||||
@ -87,15 +92,25 @@ export class LevelCache extends AbstractCache {
|
||||
]);
|
||||
}
|
||||
|
||||
// cache maintenance
|
||||
/**
|
||||
* cleans the cache
|
||||
*/
|
||||
public async clean(): Promise<void> {
|
||||
public async deleteCacheEntryByKey(keyArg) {
|
||||
await Promise.all([
|
||||
this.cacheDiskManager.clean(),
|
||||
this.cacheDiskManager.clean(),
|
||||
this.cacheS3Manager.clean(),
|
||||
this.cacheMemoryManager.deleteCacheEntryByKey(keyArg),
|
||||
this.cacheDiskManager.deleteCacheEntryByKey(keyArg),
|
||||
this.cacheS3Manager.deleteCacheEntryByKey(keyArg),
|
||||
]);
|
||||
}
|
||||
|
||||
// cache maintenance
|
||||
public async cleanOutdated() {}
|
||||
|
||||
/**
|
||||
* cleans the complete cache
|
||||
*/
|
||||
public async cleanAll(): Promise<void> {
|
||||
await Promise.all([
|
||||
this.cacheDiskManager.cleanAll(),
|
||||
this.cacheDiskManager.cleanAll(),
|
||||
this.cacheS3Manager.cleanAll(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user