Skip to main content
Glama
cache.ts4.51 kB
/** * Cache System * Provides high-performance caching with LRU (Least Recently Used) strategy * * 缓存系统 * 提供基于LRU(最近最少使用)策略的高性能缓存 */ import { LRUCache } from 'lru-cache'; import { log, LogLevel } from './logging.js'; // Cache TTL settings for different data types (in milliseconds) // 不同数据类型的缓存TTL设置(毫秒) const CACHE_TTL = { ticker: 10 * 1000, // Ticker data: 10 seconds orderbook: 5 * 1000, // Order book: 5 seconds markets: 60 * 60 * 1000, // Markets data: 1 hour ohlcv: 60 * 1000, // OHLCV data: 1 minute trades: 30 * 1000, // Recent trades: 30 seconds status: 5 * 60 * 1000, // Exchange status: 5 minutes }; // Cache statistics // 缓存统计 export const cacheStats = { hits: 0, misses: 0, size: 0, lastCleared: new Date().toISOString() }; // Create high-performance LRU cache // 创建高性能LRU缓存 const dataCache = new LRUCache({ max: 1000, // Max cache items: 1000 ttl: 30 * 1000, // Default TTL: 30 seconds updateAgeOnGet: true, // Update item age on access allowStale: false, // Don't return stale items }); /** * Determine TTL based on key pattern * @param key Cache key * @returns TTL in milliseconds * * 根据键模式确定TTL * @param key 缓存键 * @returns TTL(毫秒) */ function getTtl(key: string): number { if (key.startsWith('ticker:')) return CACHE_TTL.ticker; if (key.startsWith('orderbook:')) return CACHE_TTL.orderbook; if (key.startsWith('markets:')) return CACHE_TTL.markets; if (key.startsWith('ohlcv:')) return CACHE_TTL.ohlcv; if (key.startsWith('trades:')) return CACHE_TTL.trades; if (key.startsWith('status:')) return CACHE_TTL.status; return 30 * 1000; // Default: 30 seconds } /** * Get data from cache or fetch using provided function * @param key Cache key * @param fetchFn Function to fetch data if not in cache * @param customTtl Optional custom TTL in milliseconds * @returns Cached data or newly fetched data * * 从缓存获取数据或使用提供的函数获取 * @param key 缓存键 * @param fetchFn 如果缓存中没有数据,用于获取数据的函数 * @param customTtl 可选的自定义TTL(毫秒) * @returns 缓存数据或新获取的数据 */ export async function getCachedData<T>( key: string, fetchFn: () => Promise<T>, customTtl?: number ): Promise<T> { // Try to get from cache first const cached = dataCache.get(key) as T; if (cached) { log(LogLevel.DEBUG, `Cache hit: ${key}`); cacheStats.hits++; return cached; } // Cache miss, fetch data log(LogLevel.DEBUG, `Cache miss: ${key}, fetching data`); cacheStats.misses++; try { const data = await fetchFn(); const ttl = customTtl || getTtl(key); dataCache.set(key, data as any, { ttl }); cacheStats.size = dataCache.size; return data; } catch (error) { log(LogLevel.ERROR, `Error fetching data for key ${key}: ${error}`); throw error; } } /** * Clear cache * @param keyPattern Optional key pattern to clear specific keys * * 清除缓存 * @param keyPattern 可选的键模式,用于清除特定模式的键 */ export function clearCache(keyPattern?: string): void { if (keyPattern) { // Clear all keys matching specific pattern const keys = []; for (const key of dataCache.keys()) { if (typeof key === 'string' && key.includes(keyPattern)) { keys.push(key); } } // Delete all matching keys from cache keys.forEach(key => dataCache.delete(key)); log(LogLevel.INFO, `Cleared ${keys.length} cache items matching "${keyPattern}"`); } else { // Clear entire cache const size = dataCache.size; dataCache.clear(); log(LogLevel.INFO, `Cleared all ${size} cache items`); } // Update cache statistics cacheStats.size = dataCache.size; cacheStats.lastCleared = new Date().toISOString(); cacheStats.hits = 0; cacheStats.misses = 0; } /** * Get cache statistics * @returns Cache statistics object * * 获取缓存统计信息 * @returns 缓存统计对象 */ export function getCacheStats() { return { hits: cacheStats.hits, misses: cacheStats.misses, hitRatio: cacheStats.hits + cacheStats.misses > 0 ? (cacheStats.hits / (cacheStats.hits + cacheStats.misses)).toFixed(2) : '0.00', size: dataCache.size, maxSize: dataCache.max, lastCleared: cacheStats.lastCleared }; }

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/doggybee/mcp-server-ccxt'

If you have feedback or need assistance with the MCP directory API, please join our Discord server