/** * CacheManager - Shared caching utility for all executor services * * Provides a three-tier caching strategy: * - Internal (in-memory): Fastest layer using Map with LRU eviction * - Redis (local/fast): Secondary cache layer for distributed reads * - Remote (persistent): Backing store synced on writes/deletes/cache misses * * Used by: StorageService, DatabaseService, GraphService, VectorService, * QuotaService, FallbackService, AgentsService, SessionsService, BrokersService, * NotificationsService, etc. */ import type { Redis as IORedisClient } from 'ioredis'; import { EnvType } from '../types'; /** * Cache log levels */ type CacheLogLevel = 'debug' | 'info' | 'warn' | 'error'; /** * Cache logger configuration */ interface ICacheLoggerConfig { /** Enable logging */ enabled: boolean; /** Minimum log level to display */ level: CacheLogLevel; /** Include timestamps */ timestamps: boolean; /** Include stack traces for errors */ stackTraces: boolean; } /** * Cache logger for detailed operation tracking */ export declare class CacheLogger { private config; private readonly levelPriority; constructor(config?: Partial); setConfig(config: Partial): void; enable(): void; disable(): void; private shouldLog; private formatMessage; debug(component: string, message: string, data?: Record): void; info(component: string, message: string, data?: Record): void; warn(component: string, message: string, data?: Record): void; error(component: string, message: string, error?: Error, data?: Record): void; /** Log cache operation with timing */ operation(op: string, key: string, startTime: number, result: 'hit' | 'miss' | 'stored' | 'deleted' | 'error', tier: string, data?: Record): void; } /** Global cache logger instance */ export declare const cacheLogger: CacheLogger; /** * Cache value wrapper with type information for auto-detection */ export interface ICacheValueWrapper { /** Type of the cached value */ type: 'json' | 'string'; /** Serialized value */ value: string; } /** * Cache manager configuration */ export interface ICacheManagerConfig { workspace_id: string; public_key: string; user_id: string; token: string; env_type: EnvType | string; redis_client?: IORedisClient; } /** * Component types for cache operations */ export type CacheComponentType = 'storage' | 'database' | 'graph' | 'vector' | 'session' | 'broker' | 'notification'; /** * Options for cache operations */ export interface ICacheOperationOptions { /** Cache tag identifying the cache configuration */ cache_tag: string; /** Product tag */ product_tag: string; /** Component tag (e.g., storage tag, database tag, session tag) */ component_tag: string; /** Component type for reporting and key generation */ component_type: CacheComponentType | string; /** Operation name for key generation (e.g., 'create', 'verify', 'publish') */ operation?: string; /** Input data to generate cache key from */ input: unknown; /** Private key for encryption/decryption */ privateKey: string; /** Cache expiry in milliseconds */ expiry?: number; } /** * Cache fetch result */ export interface ICacheFetchResult { /** Whether cache hit occurred */ hit: boolean; /** Cached data (if hit) */ data?: T; /** Cache key used */ key: string; /** Source of data: 'internal', 'redis', 'remote', or 'miss' */ source: 'internal' | 'redis' | 'remote' | 'miss'; } /** * CacheManager provides shared caching functionality for all executor services * * @example * ```ts * const cacheManager = new CacheManager({ * workspace_id: 'ws-123', * public_key: 'pk-123', * user_id: 'user-123', * token: 'token', * env_type: 'prd', * redis_client: redisClient, * }); * * // Check cache before operation * const cached = await cacheManager.fetch({ * cache_tag: 'my-cache', * product_tag: 'my-product', * component_tag: 'my-storage', * component_type: 'storage', * input: { fileName: 'test.pdf' }, * privateKey: 'private-key', * expiry: 3600000, // 1 hour * }); * * if (cached.hit) { * return cached.data; * } * * // Execute operation... * const result = await doOperation(); * * // Store in cache (fire-and-forget - no await needed) * cacheManager.store({ * cache_tag: 'my-cache', * product_tag: 'my-product', * component_tag: 'my-storage', * component_type: 'storage', * input: { fileName: 'test.pdf' }, * privateKey: 'private-key', * expiry: 3600000, * }, result); * ``` */ export declare class CacheManager { private config; private redisClient; private processorApiService; /** Internal in-memory cache (Tier 1 - fastest) */ private internalCache; /** Maximum number of entries in internal cache before LRU eviction */ private maxInternalCacheSize; constructor(config: ICacheManagerConfig); /** * Enable cache logging */ enableLogging(config?: { level?: CacheLogLevel; timestamps?: boolean; stackTraces?: boolean; }): void; /** * Disable cache logging */ disableLogging(): void; /** * Set maximum size for internal cache */ setMaxInternalCacheSize(size: number): void; /** * Clear internal cache */ clearInternalCache(): void; /** * Set entry in internal cache with LRU eviction */ private setInternalCache; /** * Check if internal cache entry is still valid */ private isValidEntry; /** * Wrap value with type information for storage (auto-detect type) */ private wrapValue; /** * Unwrap value based on stored type */ private unwrapValue; /** * Get user access credentials for API calls */ private getUserAccess; /** * Generate cache key from cache tag and input (legacy format) */ generateKey(cache_tag: string, input: unknown): string; /** * Generate cache key with new format: cache_tag:component_type:operation:sha256(input) * Includes cache_tag for isolation between different cache configurations */ generateKeyV2(options: { cache_tag: string; component_type: string; operation: string; input: unknown; }): string; /** * Generate cache key based on options (uses V2 format if operation provided) */ private generateCacheKey; /** * Check if caching is available (Redis client connected) */ isAvailable(): boolean; /** * Fetch data from cache (Internal first, then Redis, then remote on miss) * * @returns Cache result with hit status, data, and source */ fetch(options: ICacheOperationOptions): Promise>; /** * Store data in cache (all three tiers: internal, Redis, and remote) */ /** * Store data in cache - fire-and-forget pattern. * Internal cache is written synchronously for immediate availability. * Redis and remote cache writes happen asynchronously without blocking. */ store(options: ICacheOperationOptions, data: T): void; /** * Internal method to store to Redis and remote cache asynchronously */ private storeToExternalTiers; /** * Invalidate/delete data from cache (all three tiers) */ invalidate(cache_tag: string, input: unknown): Promise; /** * Invalidate/delete data from cache using options (supports new key format) */ invalidateV2(options: ICacheOperationOptions): Promise; /** * Helper method to wrap an async operation with caching * * @example * ```ts * const result = await cacheManager.withCache( * { * cache_tag: 'my-cache', * product_tag: 'my-product', * component_tag: 'my-storage', * component_type: 'storage', * input: { fileName: 'test.pdf' }, * privateKey: 'private-key', * expiry: 3600000, * }, * async () => { * // Execute the actual operation * return await downloadFile('test.pdf'); * } * ); * ``` */ withCache(options: ICacheOperationOptions, operation: () => Promise): Promise<{ data: T; cached: boolean; source: 'internal' | 'redis' | 'remote' | 'fresh'; }>; /** * Get internal cache stats for debugging/monitoring */ getInternalCacheStats(): { size: number; maxSize: number; utilizationPercent: number; redisAvailable: boolean; }; /** * Get detailed cache statistics including entry ages */ getDetailedStats(): { internal: { size: number; maxSize: number; utilizationPercent: number; oldestEntryAge: number | null; newestEntryAge: number | null; }; redis: { available: boolean; }; remote: { available: boolean; }; }; } export default CacheManager;