This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

semble / src / shared / infrastructure / events / BullMQEventPublisher.ts
2.3 kB 76 lines
1import { Queue } from 'bullmq'; 2import Redis from 'ioredis'; 3import { IEventPublisher } from '../../application/events/IEventPublisher'; 4import { IDomainEvent } from '../../domain/events/IDomainEvent'; 5import { Result, ok, err } from '../../core/Result'; 6import { QueueNames, QueueOptions, QueueName } from './QueueConfig'; 7import { EventMapper } from './EventMapper'; 8import { EventName, EventNames } from './EventConfig'; 9 10export class BullMQEventPublisher implements IEventPublisher { 11 private queues: Map<string, Queue> = new Map(); 12 13 constructor(private redisConnection: Redis) {} 14 15 async publishEvents(events: IDomainEvent[]): Promise<Result<void>> { 16 try { 17 for (const event of events) { 18 await this.publishSingleEvent(event); 19 } 20 return ok(undefined); 21 } catch (error) { 22 return err(error as Error); 23 } 24 } 25 26 private async publishSingleEvent(event: IDomainEvent): Promise<void> { 27 const targetQueues = this.getTargetQueues(event.eventName); 28 29 for (const queueName of targetQueues) { 30 await this.publishToQueue(queueName, event); 31 } 32 } 33 34 private async publishToQueue( 35 queueName: QueueName, 36 event: IDomainEvent, 37 ): Promise<void> { 38 if (!this.queues.has(queueName)) { 39 this.queues.set( 40 queueName, 41 new Queue(queueName, { 42 connection: this.redisConnection, 43 defaultJobOptions: QueueOptions[queueName], 44 }), 45 ); 46 } 47 48 const queue = this.queues.get(queueName)!; 49 const serializedEvent = EventMapper.toSerialized(event); 50 await queue.add(serializedEvent.eventType, serializedEvent); 51 } 52 53 private getTargetQueues(eventName: EventName): QueueName[] { 54 switch (eventName) { 55 case EventNames.CARD_ADDED_TO_LIBRARY: 56 return [ 57 QueueNames.FEEDS, 58 QueueNames.SEARCH, 59 QueueNames.NOTIFICATIONS, 60 QueueNames.SYNC, 61 ]; 62 case EventNames.CARD_ADDED_TO_COLLECTION: 63 return [QueueNames.FEEDS, QueueNames.NOTIFICATIONS]; 64 case EventNames.CARD_REMOVED_FROM_LIBRARY: 65 return [QueueNames.NOTIFICATIONS]; 66 default: 67 return [QueueNames.FEEDS]; 68 } 69 } 70 71 async close(): Promise<void> { 72 await Promise.all( 73 Array.from(this.queues.values()).map((queue) => queue.close()), 74 ); 75 } 76}