@heavybit/cache-package
v2.0.0
Published
Shared cache package that allows microservices to set, get and delete cache data
Readme
Heavybit Cache Package
A comprehensive Redis caching package with support for multiple data structures, a circuit breaker pattern, and robust connection management. Designed to be instantiated via dependency injection, this service provides built-in error handling, structured logging via Winston, and health monitoring capabilities.
Features
- Dependency Injection: Instantiate the service with explicit configuration and your application's Winston logger.
- Circuit Breaker: Protects against Redis failures with automatic recovery.
- Multiple Data Structures: Supports strings, hashes, JSON, lists, and sets.
- Concurrency Management: Configurable concurrency limits to prevent Redis overload.
- Environment Isolation: Automatic key prefixing based on the environment.
- Comprehensive Error Handling: Promise-based timeout protection and graceful degradation on every operation.
- Health Monitoring: Built-in health checks.
Installation
npm install @heavybit/cache-package ioredis winstonBasic Setup & Usage
The CacheService requires a RedisConfig object and a configured Winston logger instance.
import { createLogger, transports, format } from 'winston';
import { CacheService } from '@heavybit/cache-package';
// 1. Create your application's logger
const myLogger = createLogger({
level: 'info',
format: format.combine(
format.timestamp(),
format.json()
),
transports: [new transports.Console()]
});
// 2. Initialize the CacheService
const cache = new CacheService({
host: process.env.REDIS_HOST || '127.0.0.1',
port: parseInt(process.env.REDIS_PORT || '6379'),
environment: process.env.NODE_ENV || 'development',
maxConcurrentOps: 150,
ttl: 3600, // Default 1 hour TTL
}, myLogger);
// 3. Perform a health check
async function check() {
const isHealthy = await cache.healthCheck();
console.log('Redis is healthy:', isHealthy);
}Key Building
The service automatically builds environment-prefixed keys from objects, sorting the keys alphabetically to ensure consistency:
const keyObj = { userId: 123, type: 'profile' };
// Generates key: "production|type:profile|userId:123"Error Handling
The service includes comprehensive error handling to ensure your application doesn't crash if Redis goes down:
Circuit Breaker: Automatically opens when Redis hits max clients or connection limits.
Operation Timeouts: Every single operation is wrapped in a strict
Promise.racetimeout to prevent hanging event loops.Retry Logic: Configurable reconnect strategy built into the initialization.
Graceful Degradation: Operations fail fast and cleanly when the circuit is open.
try {
const data = await cache.getCache(keyObj);
} catch (error) {
if (error.message === 'Redis circuit breaker is open') {
console.log('Redis is temporarily unavailable, falling back to DB...');
} else if (error.message === 'Redis operation limit reached') {
console.log('Too many concurrent operations.');
} else if (error.message.includes('timed out')) {
console.log('The Redis operation took too long.');
} else {
console.error('Redis operation failed:', error);
}
}