127 lines
3.2 KiB
TypeScript
127 lines
3.2 KiB
TypeScript
import { createClient, RedisClientType } from 'redis';
|
|
import { redisUrl } from './env-exporter';
|
|
|
|
class RedisClient {
|
|
private client: RedisClientType;
|
|
private subscriberClient: RedisClientType | null = null;
|
|
private isConnected: boolean = false;
|
|
|
|
constructor() {
|
|
this.client = createClient({
|
|
url: redisUrl,
|
|
});
|
|
|
|
this.client.on('error', (err) => {
|
|
console.error('Redis Client Error:', err);
|
|
});
|
|
|
|
this.client.on('connect', () => {
|
|
console.log('Redis Client Connected');
|
|
this.isConnected = true;
|
|
});
|
|
|
|
this.client.on('disconnect', () => {
|
|
console.log('Redis Client Disconnected');
|
|
this.isConnected = false;
|
|
});
|
|
|
|
this.client.on('ready', () => {
|
|
console.log('Redis Client Ready');
|
|
});
|
|
|
|
this.client.on('reconnecting', () => {
|
|
console.log('Redis Client Reconnecting');
|
|
});
|
|
|
|
// Connect immediately (fire and forget)
|
|
this.client.connect().catch((err) => {
|
|
console.error('Failed to connect Redis:', err);
|
|
});
|
|
}
|
|
|
|
async set(key: string, value: string, ttlSeconds?: number): Promise<string | null> {
|
|
if (ttlSeconds) {
|
|
return await this.client.setEx(key, ttlSeconds, value);
|
|
} else {
|
|
return await this.client.set(key, value);
|
|
}
|
|
}
|
|
|
|
async get(key: string): Promise<string | null> {
|
|
return await this.client.get(key);
|
|
}
|
|
|
|
async exists(key: string): Promise<boolean> {
|
|
const result = await this.client.exists(key);
|
|
return result === 1;
|
|
}
|
|
|
|
async delete(key: string): Promise<number> {
|
|
return await this.client.del(key);
|
|
}
|
|
|
|
async lPush(key: string, value: string): Promise<number> {
|
|
return await this.client.lPush(key, value);
|
|
}
|
|
|
|
async KEYS(pattern: string): Promise<string[]> {
|
|
return await this.client.KEYS(pattern);
|
|
}
|
|
|
|
async MGET(keys: string[]): Promise<(string | null)[]> {
|
|
return await this.client.MGET(keys);
|
|
}
|
|
|
|
// Publish message to a channel
|
|
async publish(channel: string, message: string): Promise<number> {
|
|
return await this.client.publish(channel, message);
|
|
}
|
|
|
|
// Subscribe to a channel with callback
|
|
async subscribe(channel: string, callback: (message: string) => void): Promise<void> {
|
|
if (!this.subscriberClient) {
|
|
this.subscriberClient = createClient({
|
|
url: redisUrl,
|
|
});
|
|
|
|
this.subscriberClient.on('error', (err) => {
|
|
console.error('Redis Subscriber Error:', err);
|
|
});
|
|
|
|
this.subscriberClient.on('connect', () => {
|
|
console.log('Redis Subscriber Connected');
|
|
});
|
|
|
|
await this.subscriberClient.connect();
|
|
}
|
|
|
|
await this.subscriberClient.subscribe(channel, callback);
|
|
console.log(`Subscribed to channel: ${channel}`);
|
|
}
|
|
|
|
// Unsubscribe from a channel
|
|
async unsubscribe(channel: string): Promise<void> {
|
|
if (this.subscriberClient) {
|
|
await this.subscriberClient.unsubscribe(channel);
|
|
console.log(`Unsubscribed from channel: ${channel}`);
|
|
}
|
|
}
|
|
|
|
disconnect(): void {
|
|
if (this.isConnected) {
|
|
this.client.disconnect();
|
|
}
|
|
if (this.subscriberClient) {
|
|
this.subscriberClient.disconnect();
|
|
}
|
|
}
|
|
|
|
get isClientConnected(): boolean {
|
|
return this.isConnected;
|
|
}
|
|
}
|
|
|
|
const redisClient = new RedisClient();
|
|
|
|
export default redisClient;
|
|
export { RedisClient };
|