Files
n8n-enterprise-unlocked/packages/cli/src/scaling/pubsub/subscriber.service.ts

61 lines
1.5 KiB
TypeScript

import type { Redis as SingleNodeClient, Cluster as MultiNodeClient } from 'ioredis';
import { Service } from 'typedi';
import config from '@/config';
import { Logger } from '@/logger';
import { RedisClientService } from '@/services/redis/redis-client.service';
import type { ScalingPubSubChannel } from './pubsub.types';
/**
* Responsible for subscribing to the pubsub channels used by scaling mode.
*/
@Service()
export class Subscriber {
private readonly client: SingleNodeClient | MultiNodeClient;
// #region Lifecycle
constructor(
private readonly logger: Logger,
private readonly redisClientService: RedisClientService,
) {
// @TODO: Once this class is only ever initialized in scaling mode, throw in the next line instead.
if (config.getEnv('executions.mode') !== 'queue') return;
this.client = this.redisClientService.createClient({ type: 'subscriber(n8n)' });
this.client.on('error', (error) => this.logger.error(error.message));
}
getClient() {
return this.client;
}
// @TODO: Use `@OnShutdown()` decorator
shutdown() {
this.client.disconnect();
}
// #endregion
// #region Subscribing
async subscribe(channel: ScalingPubSubChannel) {
await this.client.subscribe(channel, (error) => {
if (error) {
this.logger.error('Failed to subscribe to channel', { channel, cause: error });
return;
}
this.logger.debug('Subscribed to channel', { channel });
});
}
addMessageHandler(handlerFn: (channel: string, msg: string) => void) {
this.client.on('message', handlerFn);
}
// #endregion
}