move source into src dir
This commit is contained in:
75
src/classes/caching/file_system_cache.js
Normal file
75
src/classes/caching/file_system_cache.js
Normal file
@ -0,0 +1,75 @@
|
||||
import cacache from 'cacache';
|
||||
import { Readable } from 'stream';
|
||||
import { KeyTimeout } from './key_timeout.js';
|
||||
|
||||
function getBodyAndMetaKeys(key) {
|
||||
return [`${key}body`, `${key}meta`];
|
||||
}
|
||||
|
||||
export class FileSystemCache {
|
||||
constructor(options = {}) {
|
||||
this.ttl = options.ttl;
|
||||
this.keyTimeout = new KeyTimeout();
|
||||
this.cacheDirectory = options.cacheDirectory || '.cache';
|
||||
}
|
||||
|
||||
async get(key) {
|
||||
const [, metaKey] = getBodyAndMetaKeys(key);
|
||||
|
||||
const metaInfo = await cacache.get.info(this.cacheDirectory, metaKey);
|
||||
|
||||
if (!metaInfo) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const metaBuffer = await cacache.get.byDigest(this.cacheDirectory, metaInfo.integrity);
|
||||
const metaData = JSON.parse(metaBuffer);
|
||||
const { bodyStreamIntegrity, bodyStreamLength } = metaData;
|
||||
delete metaData.bodyStreamIntegrity;
|
||||
delete metaData.bodyStreamLength;
|
||||
|
||||
const bodyStream = bodyStreamLength > 0
|
||||
? cacache.get.stream.byDigest(this.cacheDirectory, bodyStreamIntegrity)
|
||||
: Readable.from(Buffer.alloc(0));
|
||||
|
||||
return {
|
||||
bodyStream,
|
||||
metaData,
|
||||
};
|
||||
}
|
||||
|
||||
remove(key) {
|
||||
const [bodyKey, metaKey] = getBodyAndMetaKeys(key);
|
||||
|
||||
this.keyTimeout.clearTimeout(key);
|
||||
|
||||
return Promise.all([
|
||||
cacache.rm.entry(this.cacheDirectory, bodyKey),
|
||||
cacache.rm.entry(this.cacheDirectory, metaKey),
|
||||
]);
|
||||
}
|
||||
|
||||
async set(key, bodyStream, metaData, bodyStreamLength) {
|
||||
const [bodyKey, metaKey] = getBodyAndMetaKeys(key);
|
||||
const metaCopy = { ...metaData, bodyStreamLength };
|
||||
|
||||
this.keyTimeout.clearTimeout(key);
|
||||
|
||||
if (bodyStreamLength > 0) {
|
||||
metaCopy.bodyStreamIntegrity = await new Promise((fulfill, reject) => {
|
||||
bodyStream.pipe(cacache.put.stream(this.cacheDirectory, bodyKey))
|
||||
.on('integrity', (i) => fulfill(i))
|
||||
.on('error', (e) => {
|
||||
reject(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const metaBuffer = Buffer.from(JSON.stringify(metaCopy));
|
||||
await cacache.put(this.cacheDirectory, metaKey, metaBuffer);
|
||||
|
||||
if (typeof this.ttl === 'number') {
|
||||
this.keyTimeout.updateTimeout(key, this.ttl, () => this.remove(key));
|
||||
}
|
||||
}
|
||||
}
|
16
src/classes/caching/key_timeout.js
Normal file
16
src/classes/caching/key_timeout.js
Normal file
@ -0,0 +1,16 @@
|
||||
export class KeyTimeout {
|
||||
constructor() {
|
||||
this.timeoutHandleForKey = {};
|
||||
}
|
||||
|
||||
clearTimeout(key) {
|
||||
clearTimeout(this.timeoutHandleForKey[key]);
|
||||
}
|
||||
|
||||
updateTimeout(key, durationMs, callback) {
|
||||
this.clearTimeout(key);
|
||||
this.timeoutHandleForKey[key] = setTimeout(() => {
|
||||
callback();
|
||||
}, durationMs);
|
||||
}
|
||||
}
|
45
src/classes/caching/memory_cache.js
Normal file
45
src/classes/caching/memory_cache.js
Normal file
@ -0,0 +1,45 @@
|
||||
import { Readable } from 'stream';
|
||||
import { KeyTimeout } from './key_timeout.js';
|
||||
|
||||
function streamToBuffer(stream) {
|
||||
const chunks = [];
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)));
|
||||
stream.on('error', (err) => reject(err));
|
||||
stream.on('end', () => resolve(Buffer.concat(chunks)));
|
||||
});
|
||||
}
|
||||
|
||||
export class MemoryCache {
|
||||
constructor(options = {}) {
|
||||
this.ttl = options.ttl;
|
||||
this.keyTimeout = new KeyTimeout();
|
||||
this.cache = {};
|
||||
}
|
||||
|
||||
get(key) {
|
||||
const cachedValue = this.cache[key];
|
||||
if (cachedValue) {
|
||||
return {
|
||||
bodyStream: Readable.from(cachedValue.bodyBuffer),
|
||||
metaData: cachedValue.metaData,
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
remove(key) {
|
||||
this.keyTimeout.clearTimeout(key);
|
||||
delete this.cache[key];
|
||||
}
|
||||
|
||||
async set(key, bodyStream, metaData) {
|
||||
const bodyBuffer = await streamToBuffer(bodyStream);
|
||||
this.cache[key] = { bodyBuffer, metaData };
|
||||
|
||||
if (typeof this.ttl === 'number') {
|
||||
this.keyTimeout.updateTimeout(key, this.ttl, () => this.remove(key));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user