chore: overhaul infrastructure and integrate @mintel packages
Some checks failed
🧪 CI (QA) / 🧪 Quality Assurance (push) Failing after 1m3s
Some checks failed
🧪 CI (QA) / 🧪 Quality Assurance (push) Failing after 1m3s
- Restructure to pnpm monorepo (site moved to apps/web) - Integrate @mintel/tsconfig, @mintel/eslint-config, @mintel/husky-config - Implement Docker service architecture (Varnish, Directus, Gatekeeper) - Setup environment-aware Gitea Actions deployment
This commit is contained in:
95
apps/web/src/utils/cache/redis-adapter.ts
vendored
Normal file
95
apps/web/src/utils/cache/redis-adapter.ts
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Redis Cache Adapter
|
||||
* Decoupled Redis implementation
|
||||
*/
|
||||
|
||||
import type { CacheAdapter, CacheConfig } from './interfaces';
|
||||
|
||||
export class RedisCacheAdapter implements CacheAdapter {
|
||||
private client: any = null;
|
||||
private prefix: string;
|
||||
private defaultTTL: number;
|
||||
private redisUrl: string;
|
||||
|
||||
constructor(config: CacheConfig & { redisUrl?: string } = {}) {
|
||||
this.prefix = config.prefix || 'mintel:';
|
||||
this.defaultTTL = config.defaultTTL || 3600;
|
||||
this.redisUrl = config.redisUrl || process.env.REDIS_URL || 'redis://localhost:6379';
|
||||
}
|
||||
|
||||
private async init(): Promise<boolean> {
|
||||
if (this.client !== null) return true;
|
||||
|
||||
try {
|
||||
const Redis = await import('ioredis');
|
||||
this.client = new Redis.default(this.redisUrl);
|
||||
|
||||
this.client.on('error', (err: Error) => {
|
||||
console.warn('Redis connection error:', err.message);
|
||||
this.client = null;
|
||||
});
|
||||
|
||||
this.client.on('connect', () => {
|
||||
console.log('✅ Redis connected');
|
||||
});
|
||||
|
||||
// Test connection
|
||||
await this.client.set(this.prefix + '__test__', 'ok', 'EX', 1);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.warn('Redis unavailable:', error);
|
||||
this.client = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async get<T>(key: string): Promise<T | null> {
|
||||
const available = await this.init();
|
||||
if (!available || !this.client) return null;
|
||||
|
||||
try {
|
||||
const data = await this.client.get(this.prefix + key);
|
||||
return data ? JSON.parse(data) : null;
|
||||
} catch (error) {
|
||||
console.warn('Redis get error:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async set<T>(key: string, value: T, ttl?: number): Promise<void> {
|
||||
const available = await this.init();
|
||||
if (!available || !this.client) return;
|
||||
|
||||
try {
|
||||
const finalTTL = ttl || this.defaultTTL;
|
||||
await this.client.setex(this.prefix + key, finalTTL, JSON.stringify(value));
|
||||
} catch (error) {
|
||||
console.warn('Redis set error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async del(key: string): Promise<void> {
|
||||
const available = await this.init();
|
||||
if (!available || !this.client) return;
|
||||
|
||||
try {
|
||||
await this.client.del(this.prefix + key);
|
||||
} catch (error) {
|
||||
console.warn('Redis del error:', error);
|
||||
}
|
||||
}
|
||||
|
||||
async clear(): Promise<void> {
|
||||
const available = await this.init();
|
||||
if (!available || !this.client) return;
|
||||
|
||||
try {
|
||||
const keys = await this.client.keys(this.prefix + '*');
|
||||
if (keys.length > 0) {
|
||||
await this.client.del(...keys);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Redis clear error:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user