memorium/lib/cache/cache.ts

89 lines
1.9 KiB
TypeScript
Raw Normal View History

import {
2023-08-04 13:48:12 +02:00
Bulk,
connect,
Redis,
RedisConnectOptions,
RedisValue,
} from "https://deno.land/x/redis@v0.31.0/mod.ts";
const REDIS_HOST = Deno.env.get("REDIS_HOST");
const REDIS_PASS = Deno.env.get("REDIS_PASS") || "";
const REDIS_PORT = Deno.env.get("REDIS_PORT");
async function createCache<T>(): Promise<Map<string, T> | Redis> {
if (REDIS_HOST) {
const conf: RedisConnectOptions = {
hostname: REDIS_HOST,
port: REDIS_PORT || 6379,
2023-08-04 13:48:12 +02:00
maxRetryCount: 2,
};
if (REDIS_PASS) {
conf.password = REDIS_PASS;
}
2023-08-04 13:48:12 +02:00
try {
const client = await connect(conf);
console.log("[redis] connected");
return client;
} catch (_err) {
console.log("[cache] cant connect to redis, falling back to mock");
}
}
2023-08-04 13:48:12 +02:00
const mockRedis = new Map<string, RedisValue>();
return {
async set(key: string, value: RedisValue) {
mockRedis.set(key, value);
return value.toString();
},
async get(key: string) {
return mockRedis.get(key) as Bulk;
},
};
}
const cache = await createCache();
export async function get<T>(id: string, binary = false) {
if (binary && !(cache instanceof Map)) {
const cacheHit = await cache.sendCommand("GET", [id], {
returnUint8Arrays: true,
}) as T;
return cacheHit;
}
const cacheHit = await cache.get(id) as T;
return cacheHit;
}
2023-08-01 18:35:35 +02:00
export function clearAll() {
if ("flushall" in cache) {
return cache.flushall();
} else {
for (const k of cache.keys()) {
cache.delete(k);
}
}
}
export function expire(id: string, seconds: number) {
if ("expire" in cache) {
return cache.expire(id, seconds);
}
}
2023-08-02 01:58:03 +02:00
type RedisOptions = {
expires?: number;
};
export async function set<T extends RedisValue>(
id: string,
content: T,
options?: RedisOptions,
) {
console.log("[cache] storing ", { id });
2023-08-02 01:58:03 +02:00
const res = await cache.set(id, content);
if (options?.expires) {
await expire(id, options.expires);
}
return res;
}