Files
CurrenciCombo/orchestrator/src/services/cache.ts
defiQUG f52313e7c6 Enhance ComboHandler and orchestrator functionality with access control and error handling improvements
- Added AccessControl to ComboHandler for role-based access management.
- Implemented gas estimation for plan execution and improved gas limit checks.
- Updated execution and preparation methods to enforce step count limits and role restrictions.
- Enhanced error handling in orchestrator API endpoints with AppError for better validation feedback.
- Integrated request timeout middleware for improved request management.
- Updated Swagger documentation to reflect new API structure and parameters.
2025-11-05 17:55:48 -08:00

108 lines
2.3 KiB
TypeScript

import Redis from "ioredis";
import express from "express";
/**
* Redis caching service
*/
let redis: Redis | null = null;
/**
* Initialize Redis connection
*/
export function initRedis(url?: string): Redis {
if (!redis) {
redis = new Redis(url || process.env.REDIS_URL || "redis://localhost:6379", {
maxRetriesPerRequest: 3,
retryStrategy: (times) => {
const delay = Math.min(times * 50, 2000);
return delay;
},
});
redis.on("error", (err) => {
console.error("Redis connection error:", err);
});
redis.on("connect", () => {
console.log("✅ Redis connected");
});
}
return redis;
}
/**
* Get Redis client
*/
export function getRedis(): Redis | null {
if (!redis && process.env.REDIS_URL) {
initRedis();
}
return redis;
}
/**
* Cache wrapper with TTL
*/
export async function cacheGet<T>(key: string): Promise<T | null> {
const client = getRedis();
if (!client) return null;
try {
const value = await client.get(key);
return value ? JSON.parse(value) : null;
} catch (error) {
console.error("Cache get error:", error);
return null;
}
}
export async function cacheSet<T>(key: string, value: T, ttlSeconds = 3600): Promise<void> {
const client = getRedis();
if (!client) return;
try {
await client.setex(key, ttlSeconds, JSON.stringify(value));
} catch (error) {
console.error("Cache set error:", error);
}
}
export async function cacheDelete(key: string): Promise<void> {
const client = getRedis();
if (!client) return;
try {
await client.del(key);
} catch (error) {
console.error("Cache delete error:", error);
}
}
/**
* Cache middleware for Express routes
*/
export function cacheMiddleware(ttlSeconds = 300) {
return async (req: express.Request, res: express.Response, next: express.NextFunction) => {
if (req.method !== "GET") {
return next();
}
const cacheKey = `cache:${req.path}:${JSON.stringify(req.query)}`;
const cached = await cacheGet(cacheKey);
if (cached) {
return res.json(cached);
}
const originalSend = res.json;
res.json = function (body: any) {
cacheSet(cacheKey, body, ttlSeconds).catch(console.error);
return originalSend.call(this, body);
};
next();
};
}