Untitled
unknown
plain_text
2 years ago
5.0 kB
20
Indexable
const { createClient } = require("redis");
const hash = require("object-hash");
const zlib = require("zlib");
let redisClient = undefined;
async function initializeRedisClient() {
try {
let redisURL = process.env.REDIS_URI;
if (!redisURL) {
throw new Error("REDIS_URI environment variable not found.");
}
redisClient = createClient({ url: redisURL });
redisClient.on("error", (error) => {
console.error("Redis client error:", error);
});
await redisClient.connect();
console.log("Connected to Redis successfully!");
} catch (error) {
console.error("Error connecting to Redis:", error);
throw error;
}
}
async function writeData(key, data, options, compression = true) {
if (!isRedisConnected()) {
console.error("Redis client is not connected.");
return;
}
try {
let dataToCache = data;
if (compression) {
dataToCache = zlib.deflateSync(data);
}
await redisClient.set(key, dataToCache, options);
console.log("Data cached successfully for key:", key);
} catch (error) {
console.error(`Failed to cache data for key=${key}:`, error);
}
}
async function allRedisKeys(req, res, next) {
try {
if (!isRedisConnected()) {
return res.status(500).json({ message: "Unable to retrieve keys. Redis connection not available." });
}
redisClient.keys("*", (err, keys) => {
if (err) {
console.error("Error retrieving keys from Redis:", err);
return res.status(500).json({ message: "Internal server error." });
}
return res.status(200).json({ keys });
});
} catch (error) {
console.error("Error retrieving keys from Redis:", error);
next(error);
}
}
async function flushAllData(req, res, next) {
try {
if (!isRedisConnected()) {
return res.status(500).json({ message: "Unable to flush keys. Redis connection not available." });
}
redisClient.flushall((err, result) => {
if (err) {
console.error("Error flushing keys from Redis:", err);
return res.status(500).json({ message: "Internal server error." });
}
return res.status(200).json({ message: "All keys flushed successfully." });
});
} catch (error) {
console.error("Error flushing keys from Redis:", error);
next(error);
}
}
async function readData(key, compression = true) {
if (!isRedisConnected()) {
console.error("Redis client is not connected.");
return;
}
try {
const cachedValue = await redisClient.get(key);
if (cachedValue) {
if (compression) {
return zlib.inflateSync(cachedValue).toString();
}
return cachedValue;
}
return cachedValue;
} catch (error) {
console.error(`Error reading data for key=${key}:`, error);
return;
}
}
function isRedisConnected() {
return redisClient && redisClient.status === "ready";
}
function requestToKey(req) {
const reqDataToHash = {
method: req.method,
path: req.path,
query: req.query,
body: req.body
};
return `${req.method}:${req.path}@${hash.sha1(reqDataToHash)}`;
}
function redisCachingMiddleware(compression = true) {
return async (req, res, next) => {
if (isRedisConnected()) {
const key = requestToKey(req);
const expirationTime = req.query.expiration || 300; // Default expiration: 5 minutes (300 seconds)
const cachedValue = await readData(key, compression);
if (cachedValue) {
try {
console.log("Cache Hit");
return res.json(JSON.parse(cachedValue));
} catch {
console.log("Cache Hit");
return res.send(cachedValue);
}
} else {
console.log("Cache Miss");
const oldSend = res.send;
res.send = function (data) {
res.send = oldSend;
if (res.statusCode.toString().startsWith("2")) {
const options = { EX: expirationTime };
writeData(key, data, options, compression).then();
}
return res.send(data);
};
next();
}
} else {
next();
}
};
}
module.exports = { initializeRedisClient, allRedisKeys, flushAllData, readData, requestToKey, redisCachingMiddleware };
Editor is loading...
Leave a Comment