-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
308 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { Inject, Injectable, OnModuleDestroy } from '@nestjs/common' | ||
import { ConfigType } from '@nestjs/config' | ||
import queueConfig from '../config/queue.config' | ||
import Queue = require('bull') | ||
import Debug from 'debug' | ||
import { QueueMeta, QueueProcessor, QueueTypes } from './meta.types' | ||
import { QueueService } from './queue.service' | ||
|
||
const debug = Debug('app:queue:bull') | ||
|
||
@Injectable() | ||
export class BullQueueService implements OnModuleDestroy, QueueService { | ||
private readonly queueMap: Map<QueueTypes, Queue.Queue<QueueMeta>> | ||
|
||
constructor( | ||
@Inject(queueConfig.KEY) queueCfg: ConfigType<typeof queueConfig>, | ||
) { | ||
this.queueMap = new Map() | ||
for (const key of ['ocr', 'message'] as const) { | ||
this.setQueue( | ||
key, | ||
new Queue(key, { | ||
redis: queueCfg.redis, | ||
prefix: queueCfg.redis.keyPrefix, | ||
}), | ||
) | ||
} | ||
} | ||
|
||
private setQueue<T extends QueueTypes>( | ||
key: T, | ||
queue: Queue.Queue<QueueMeta<T>>, | ||
) { | ||
this.queueMap.set(key, queue) | ||
} | ||
|
||
private getQueue<T extends QueueTypes>(key: T): Queue.Queue<QueueMeta<T>> { | ||
if (!this.queueMap.has(key)) { | ||
throw new Error(`queue ${key} not found`) | ||
} | ||
return this.queueMap.get(key) as Queue.Queue<QueueMeta<T>> | ||
} | ||
|
||
public async onModuleDestroy() { | ||
for (const key of this.queueMap.keys()) { | ||
await this.getQueue(key).close() | ||
} | ||
} | ||
|
||
public async process<T extends QueueTypes>( | ||
queue: T, | ||
handler: QueueProcessor<T>, | ||
concurrency = 1, | ||
) { | ||
debug(`setup process handler for queue ${queue}`, handler) | ||
await this.getQueue(queue).process(concurrency, (job, done) => { | ||
const debug = Debug(`app:queue:bull:${queue}:${job.id}`) | ||
debug(`running`, job.data) | ||
handler(job.data).then( | ||
() => { | ||
debug('finished') | ||
done() | ||
}, | ||
(err) => { | ||
debug('error', err) | ||
done(err) | ||
}, | ||
) | ||
}) | ||
} | ||
|
||
public async add<T extends QueueTypes>( | ||
queue: T, | ||
data: QueueMeta<T>, | ||
): Promise<void> { | ||
debug(`adding job to queue ${queue}`) | ||
await this.getQueue(queue).add(data) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Injectable } from '@nestjs/common' | ||
import { Job } from 'bull' | ||
import { | ||
OCRMeta, | ||
MessageMeta, | ||
QueueProcessor, | ||
QueueMeta, | ||
QueueTypes, | ||
} from './meta.types' | ||
import { QueueService } from './queue.service' | ||
|
||
@Injectable() | ||
export class MemoryQueueService implements QueueService { | ||
private processors = new Map<QueueTypes, QueueProcessor<any>>() | ||
|
||
public async process<T extends keyof { ocr: OCRMeta; message: MessageMeta }>( | ||
queue: T, | ||
handler: QueueProcessor<T>, | ||
concurrency: number, | ||
): Promise<void> { | ||
this.processors.set(queue, handler) | ||
} | ||
|
||
public async add<T extends keyof { ocr: OCRMeta; message: MessageMeta }>( | ||
queue: T, | ||
data: QueueMeta<T>, | ||
): Promise<void> { | ||
const processor = this.processors.get(queue) | ||
if (!processor) { | ||
throw new Error(`Queue ${queue} processor not found`) | ||
} | ||
await processor(data) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { MessageIndex } from '../search/meili-search.service' | ||
|
||
export type OCRMeta = { | ||
image: Buffer | ||
message: Omit<MessageIndex, 'text'> | ||
} | ||
|
||
export type MessageMeta = { | ||
message: MessageIndex | ||
} | ||
|
||
type QueueMetaMap = { | ||
ocr: OCRMeta | ||
message: MessageMeta | ||
} | ||
|
||
export type QueueTypes = keyof QueueMetaMap | ||
|
||
export type QueueMeta<T extends QueueTypes = QueueTypes> = QueueMetaMap[T] | ||
|
||
export type QueueProcessor<T extends QueueTypes = QueueTypes> = ( | ||
meta: QueueMeta<T>, | ||
) => Promise<void> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,27 @@ | ||
import { Module } from '@nestjs/common'; | ||
import { Module } from '@nestjs/common' | ||
import { ConfigType } from '@nestjs/config' | ||
import { ModuleRef } from '@nestjs/core' | ||
import queueConfig from 'src/config/queue.config' | ||
import { BullQueueService } from './bull-queue.service' | ||
import { MemoryQueueService } from './memory-queue.service' | ||
import { QueueService } from './queue.service' | ||
|
||
@Module({}) | ||
@Module({ | ||
providers: [ | ||
{ | ||
provide: QueueService, | ||
useFactory: ( | ||
moduleRef: ModuleRef, | ||
queueCfg: ConfigType<typeof queueConfig>, | ||
) => { | ||
if (queueCfg.enable) { | ||
return moduleRef.get(BullQueueService) | ||
} else { | ||
return moduleRef.get(MemoryQueueService) | ||
} | ||
}, | ||
inject: [ModuleRef, queueConfig.KEY], | ||
}, | ||
], | ||
}) | ||
export class QueueModule {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { QueueMeta, QueueProcessor, QueueTypes } from './meta.types' | ||
|
||
export abstract class QueueService { | ||
public abstract process<T extends QueueTypes>( | ||
queue: T, | ||
handler: QueueProcessor<T>, | ||
concurrency: number, | ||
): Promise<void> | ||
|
||
public abstract add<T extends QueueTypes>( | ||
queue: T, | ||
data: QueueMeta<T>, | ||
): Promise<void> | ||
} |
Oops, something went wrong.