fixes for redis event memory leak
This commit is contained in:
parent
9825e99540
commit
fdb8823df7
2 changed files with 39 additions and 14 deletions
35
libs/cache/src/index.ts
vendored
35
libs/cache/src/index.ts
vendored
|
|
@ -2,6 +2,9 @@ import { RedisCache } from './redis-cache';
|
||||||
import { RedisConnectionManager } from './connection-manager';
|
import { RedisConnectionManager } from './connection-manager';
|
||||||
import type { CacheProvider, CacheOptions } from './types';
|
import type { CacheProvider, CacheOptions } from './types';
|
||||||
|
|
||||||
|
// Cache instances registry to prevent multiple instances with same prefix
|
||||||
|
const cacheInstances = new Map<string, CacheProvider>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a Redis cache instance with trading-optimized defaults
|
* Create a Redis cache instance with trading-optimized defaults
|
||||||
*/
|
*/
|
||||||
|
|
@ -14,6 +17,20 @@ export function createCache(options: Partial<CacheOptions> = {}): CacheProvider
|
||||||
...options
|
...options
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For shared connections, reuse cache instances with the same key prefix
|
||||||
|
if (defaultOptions.shared) {
|
||||||
|
const cacheKey = `${defaultOptions.keyPrefix}-${defaultOptions.ttl}`;
|
||||||
|
|
||||||
|
if (cacheInstances.has(cacheKey)) {
|
||||||
|
return cacheInstances.get(cacheKey)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cache = new RedisCache(defaultOptions);
|
||||||
|
cacheInstances.set(cacheKey, cache);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For non-shared connections, always create new instances
|
||||||
return new RedisCache(defaultOptions);
|
return new RedisCache(defaultOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,45 +38,39 @@ export function createCache(options: Partial<CacheOptions> = {}): CacheProvider
|
||||||
* Create a cache instance for trading data
|
* Create a cache instance for trading data
|
||||||
*/
|
*/
|
||||||
export function createTradingCache(options: Partial<CacheOptions> = {}): CacheProvider {
|
export function createTradingCache(options: Partial<CacheOptions> = {}): CacheProvider {
|
||||||
const defaultOptions: CacheOptions = {
|
return createCache({
|
||||||
keyPrefix: 'trading:',
|
keyPrefix: 'trading:',
|
||||||
ttl: 3600, // 1 hour default
|
ttl: 3600, // 1 hour default
|
||||||
enableMetrics: true,
|
enableMetrics: true,
|
||||||
shared: true,
|
shared: true,
|
||||||
...options
|
...options
|
||||||
};
|
});
|
||||||
|
|
||||||
return new RedisCache(defaultOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a cache for market data with shorter TTL
|
* Create a cache for market data with shorter TTL
|
||||||
*/
|
*/
|
||||||
export function createMarketDataCache(options: Partial<CacheOptions> = {}): CacheProvider {
|
export function createMarketDataCache(options: Partial<CacheOptions> = {}): CacheProvider {
|
||||||
const defaultOptions: CacheOptions = {
|
return createCache({
|
||||||
keyPrefix: 'market:',
|
keyPrefix: 'market:',
|
||||||
ttl: 300, // 5 minutes for market data
|
ttl: 300, // 5 minutes for market data
|
||||||
enableMetrics: true,
|
enableMetrics: true,
|
||||||
shared: true,
|
shared: true,
|
||||||
...options
|
...options
|
||||||
};
|
});
|
||||||
|
|
||||||
return new RedisCache(defaultOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a cache for indicators with longer TTL
|
* Create a cache for indicators with longer TTL
|
||||||
*/
|
*/
|
||||||
export function createIndicatorCache(options: Partial<CacheOptions> = {}): CacheProvider {
|
export function createIndicatorCache(options: Partial<CacheOptions> = {}): CacheProvider {
|
||||||
const defaultOptions: CacheOptions = {
|
return createCache({
|
||||||
keyPrefix: 'indicators:',
|
keyPrefix: 'indicators:',
|
||||||
ttl: 1800, // 30 minutes for indicators
|
ttl: 1800, // 30 minutes for indicators
|
||||||
enableMetrics: true,
|
enableMetrics: true,
|
||||||
shared: true,
|
shared: true,
|
||||||
...options
|
...options
|
||||||
};
|
});
|
||||||
|
|
||||||
return new RedisCache(defaultOptions);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Export types and classes
|
// Export types and classes
|
||||||
|
|
|
||||||
16
libs/cache/src/redis-cache.ts
vendored
16
libs/cache/src/redis-cache.ts
vendored
|
|
@ -42,7 +42,13 @@ export class RedisCache implements CacheProvider {
|
||||||
singleton: options.shared ?? true, // Default to shared connection for cache
|
singleton: options.shared ?? true, // Default to shared connection for cache
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Only setup event handlers for non-shared connections to avoid memory leaks
|
||||||
|
if (!(options.shared ?? true)) {
|
||||||
this.setupEventHandlers();
|
this.setupEventHandlers();
|
||||||
|
} else {
|
||||||
|
// For shared connections, just monitor the connection status without adding handlers
|
||||||
|
this.isConnected = this.redis.status === 'ready';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private setupEventHandlers(): void {
|
private setupEventHandlers(): void {
|
||||||
|
|
@ -235,6 +241,14 @@ export class RedisCache implements CacheProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
isReady(): boolean {
|
isReady(): boolean {
|
||||||
return this.redis.status === 'ready';
|
// Always check the actual Redis connection status
|
||||||
|
const ready = this.redis.status === 'ready';
|
||||||
|
|
||||||
|
// Update local flag if we're not using shared connection
|
||||||
|
if (this.isConnected !== ready) {
|
||||||
|
this.isConnected = ready;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ready;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue