Fixed 267U.pre2
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
import { redisClient } from "../db/redis.js";
|
||||
import { encode, decode } from "msgpackr";
|
||||
import config from "../config/index.js";
|
||||
export class Cache {
|
||||
ttl;
|
||||
prefix;
|
||||
constructor(name, ttlSeconds){
|
||||
this.ttl = ttlSeconds;
|
||||
this.prefix = `cache:${name}`;
|
||||
}
|
||||
prefixedKey(key) {
|
||||
return key ? `${this.prefix}:${key}` : this.prefix;
|
||||
}
|
||||
async set(key, value, transaction) {
|
||||
const _key = this.prefixedKey(key);
|
||||
const _value = Buffer.from(encode(value));
|
||||
const commander = transaction ?? redisClient;
|
||||
await commander.set(_key, _value, "EX", this.ttl);
|
||||
}
|
||||
async get(key, renew = false) {
|
||||
const _key = this.prefixedKey(key);
|
||||
const cached = await redisClient.getBuffer(_key);
|
||||
if (cached === null) return undefined;
|
||||
if (renew) await redisClient.expire(_key, this.ttl);
|
||||
return decode(cached);
|
||||
}
|
||||
async getAll(renew = false) {
|
||||
const finalPrefix = `${config.redis.prefix}:${this.prefix}:`;
|
||||
const keys = (await redisClient.keys(`${finalPrefix}*`)).map((p)=>p.substring(finalPrefix.length));
|
||||
const prefixedKeys = keys.map((p)=>this.prefixedKey(p));
|
||||
const map = new Map();
|
||||
if (keys.length === 0) {
|
||||
return map;
|
||||
}
|
||||
const values = await redisClient.mgetBuffer(prefixedKeys);
|
||||
for (const [i, key] of keys.entries()){
|
||||
const val = values[i];
|
||||
if (val !== null) {
|
||||
map.set(key, decode(val));
|
||||
}
|
||||
}
|
||||
if (renew) {
|
||||
const trans = redisClient.multi();
|
||||
for (const key of map.keys()){
|
||||
trans.expire(this.prefixedKey(key), this.ttl);
|
||||
}
|
||||
await trans.exec();
|
||||
}
|
||||
return map;
|
||||
}
|
||||
async delete(...keys) {
|
||||
if (keys.length > 0) {
|
||||
const _keys = keys.map((p)=>this.prefixedKey(p));
|
||||
await redisClient.del(_keys);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Returns if cached value exists. Otherwise, calls fetcher and caches.
|
||||
* Overwrites cached value if invalidated by the optional validator.
|
||||
*/ async fetch(key, fetcher, renew = false, validator) {
|
||||
const cachedValue = await this.get(key, renew);
|
||||
if (cachedValue !== undefined) {
|
||||
if (validator) {
|
||||
if (validator(cachedValue)) {
|
||||
// Cache HIT
|
||||
return cachedValue;
|
||||
}
|
||||
} else {
|
||||
// Cache HIT
|
||||
return cachedValue;
|
||||
}
|
||||
}
|
||||
// Cache MISS
|
||||
const value = await fetcher();
|
||||
await this.set(key, value);
|
||||
return value;
|
||||
}
|
||||
/**
|
||||
* Returns if cached value exists. Otherwise, calls fetcher and caches if the fetcher returns a value.
|
||||
* Overwrites cached value if invalidated by the optional validator.
|
||||
*/ async fetchMaybe(key, fetcher, renew = false, validator) {
|
||||
const cachedValue = await this.get(key, renew);
|
||||
if (cachedValue !== undefined) {
|
||||
if (validator) {
|
||||
if (validator(cachedValue)) {
|
||||
// Cache HIT
|
||||
return cachedValue;
|
||||
}
|
||||
} else {
|
||||
// Cache HIT
|
||||
return cachedValue;
|
||||
}
|
||||
}
|
||||
// Cache MISS
|
||||
const value = await fetcher();
|
||||
if (value !== undefined) {
|
||||
await this.set(key, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user