feat: comprehensive project structure improvements and Cloud for Sovereignty landing zone
- Add Cloud for Sovereignty landing zone architecture and deployment - Implement complete legal document management system - Reorganize documentation with improved navigation - Add infrastructure improvements (Dockerfiles, K8s, monitoring) - Add operational improvements (graceful shutdown, rate limiting, caching) - Create comprehensive project structure documentation - Add Azure deployment automation scripts - Improve repository navigation and organization
This commit is contained in:
130
packages/cache/src/redis-cache.ts
vendored
Normal file
130
packages/cache/src/redis-cache.ts
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Redis caching implementation
|
||||
* Provides cache strategy, invalidation, and warming
|
||||
*/
|
||||
|
||||
import { createLogger } from '@the-order/shared';
|
||||
import type { RedisClientType } from 'redis';
|
||||
|
||||
const logger = createLogger('redis-cache');
|
||||
|
||||
export interface CacheOptions {
|
||||
ttl?: number; // Time to live in seconds
|
||||
prefix?: string; // Key prefix
|
||||
serialize?: (value: unknown) => string;
|
||||
deserialize?: (value: string) => unknown;
|
||||
}
|
||||
|
||||
export class RedisCache {
|
||||
private client: RedisClientType;
|
||||
private defaultTTL: number;
|
||||
private prefix: string;
|
||||
|
||||
constructor(client: RedisClientType, options: CacheOptions = {}) {
|
||||
this.client = client;
|
||||
this.defaultTTL = options.ttl || 3600; // 1 hour default
|
||||
this.prefix = options.prefix || 'the-order:cache:';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value from cache
|
||||
*/
|
||||
async get<T>(key: string): Promise<T | null> {
|
||||
try {
|
||||
const fullKey = `${this.prefix}${key}`;
|
||||
const value = await this.client.get(fullKey);
|
||||
if (!value) {
|
||||
return null;
|
||||
}
|
||||
return JSON.parse(value) as T;
|
||||
} catch (err) {
|
||||
logger.warn({ err, key }, 'Cache get failed');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set value in cache
|
||||
*/
|
||||
async set(key: string, value: unknown, ttl?: number): Promise<void> {
|
||||
try {
|
||||
const fullKey = `${this.prefix}${key}`;
|
||||
const serialized = JSON.stringify(value);
|
||||
const cacheTTL = ttl || this.defaultTTL;
|
||||
await this.client.setEx(fullKey, cacheTTL, serialized);
|
||||
} catch (err) {
|
||||
logger.warn({ err, key }, 'Cache set failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete value from cache
|
||||
*/
|
||||
async delete(key: string): Promise<void> {
|
||||
try {
|
||||
const fullKey = `${this.prefix}${key}`;
|
||||
await this.client.del(fullKey);
|
||||
} catch (err) {
|
||||
logger.warn({ err, key }, 'Cache delete failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete multiple keys matching pattern
|
||||
*/
|
||||
async invalidatePattern(pattern: string): Promise<void> {
|
||||
try {
|
||||
const fullPattern = `${this.prefix}${pattern}`;
|
||||
const keys = await this.client.keys(fullPattern);
|
||||
if (keys.length > 0) {
|
||||
await this.client.del(keys);
|
||||
}
|
||||
} catch (err) {
|
||||
logger.warn({ err, pattern }, 'Cache invalidation failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all cache entries with prefix
|
||||
*/
|
||||
async clear(): Promise<void> {
|
||||
try {
|
||||
await this.invalidatePattern('*');
|
||||
} catch (err) {
|
||||
logger.warn({ err }, 'Cache clear failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warm cache with data
|
||||
*/
|
||||
async warm(entries: Array<{ key: string; value: unknown; ttl?: number }>): Promise<void> {
|
||||
try {
|
||||
await Promise.all(
|
||||
entries.map((entry) => this.set(entry.key, entry.value, entry.ttl))
|
||||
);
|
||||
logger.info({ count: entries.length }, 'Cache warmed');
|
||||
} catch (err) {
|
||||
logger.warn({ err }, 'Cache warming failed');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or set pattern (cache-aside)
|
||||
*/
|
||||
async getOrSet<T>(
|
||||
key: string,
|
||||
fetcher: () => Promise<T>,
|
||||
ttl?: number
|
||||
): Promise<T> {
|
||||
const cached = await this.get<T>(key);
|
||||
if (cached !== null) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const value = await fetcher();
|
||||
await this.set(key, value, ttl);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user