node.js - nest bull zaseban proces za redove i API
Imam nestjs aplikaciju koja izlaže nekoliko REST API-ja. Jedan od API-ja pokreće posao koji obrađuje neke zadatke. Problem je što kada se posao pokrene, aplikacija prestaje odgovarati na REST zahtjeve, što dovodi do neuspjeha provjere zdravlja od strane load balancera. Slijedio sam metodu navedenu na kraju README-a za pokretanje posebnog child procesa za obradu poslova. Međutim, posao se ne pokreće u child procesu i API zahtjevi zastaju.
Evo mog posla:
import {
BullQueueEvents,
OnQueueActive,
OnQueueEvent,
Process,
Processor,
} from 'nest-bull';
import { Job } from 'bull';
import { Logger } from '@nestjs/common';
import { AService } from './a-service';
import { AJobInterface } from '../AJobInterface';
@Processor({ name: 'a_queue' })
export class AJob {
private readonly logger = new Logger('AQueue');
constructor(private readonly service: AService) {}
@Process({
name: 'app',
concurrency: 1
})
processApp(job: Job<AJobInterface>) {
console.log('CHILD: ', process.pid);
const { jobId } = job.data;
return this.service.process(jobId);
}
@OnQueueActive()
onActive(job: Job) {
this.logger.log(
`Processing job ${job.id} of type ${job.name} with data ${JSON.stringify(
job.data,
)}...`,
);
}
@OnQueueEvent(BullQueueEvents.COMPLETED)
onCompleted(job: Job) {
this.logger.log(
`Completed job ${job.id} of type ${job.name} with result ${job.returnvalue}`,
);
}
}
Evo mog app.module.ts:
import { Module, OnModuleInit } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { DatabaseModule } from './db/module';
import { BullModule } from 'nest-bull';
import { AJob } from './worker/a-job';
import { AService } from './worker/a-service';
import { join } from 'path';
@Module({
imports: [
TypeOrmModule.forRoot(),
DatabaseModule,
BullModule.register({
name: 'a_queue',
processors: [ join(__dirname, 'worker/a-job.js') ],
options: {
redis: {
host: process.env.REDIS_URL || '127.0.0.1',
port: 6379,
showFriendlyErrorStack: true,
},
settings: {
lockDuration: 300000,
stalledInterval: 300000
},
},
}),
],
controllers: [AppController],
providers: [AppService, AJob, AService],
})
export class AppModule implements OnModuleInit {
onModuleInit() {
console.log('MAIN: ', process.pid);
}
}
Radim li nešto pogrešno?
Odgovor #1
Ispričavam se što sam objavio odgovor tako kasno. Ispostavilo se da postavljanje radnika u podsustavu nije bilo moguće. Na kraju sam napravio zaseban worker.module.ts i zaseban worker.ts te stvorio dva odvojena procesa za API i radnika.
worker.module.ts:
import { Module, OnModuleInit } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppService } from '../app.service';
import { DatabaseModule } from '../db/module';
import { BullModule } from 'nest-bull';
import { AJob } from './a-job';
import { AService } from './a-service';
import { join } from 'path';
import { Job, DoneCallback } from 'bull';
@Module({
imports: [
TypeOrmModule.forRoot(),
DatabaseModule,
BullModule.register({
name: 'a_queue',
processors: [ (job: Job, done: DoneCallback) => { done(null, job.data); } ],
options: {
redis: {
host: process.env.REDIS_URL || '127.0.0.1',
port: 6379,
password: process.env.REDIS_PWD,
showFriendlyErrorStack: true,
},
settings: {
lockDuration: 300000,
stalledInterval: 300000
},
},
}),
],
providers: [AppService, AJob, AService],
})
export class WorkerModule implements OnModuleInit {
onModuleInit() {
console.log('WORKER: ', process.pid);
}
}
worker.ts:
import { NestFactory } from '@nestjs/core';
import { WorkerModule } from './worker/worker.module';
async function bootstrap() {
const app = await NestFactory.create(WorkerModule);
app.init();
}
bootstrap();
Dok app.module.ts sada izgleda ovako:
//...imports
@Module({
imports: [
TypeOrmModule.forRoot(),
DatabaseModule,
BullModule.register({
name: 'a_queue',
processors: [ ],
options: {
redis: {
host: process.env.REDIS_URL || '127.0.0.1',
port: 6379,
showFriendlyErrorStack: true,
},
},
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements OnModuleInit {
onModuleInit() {
console.log('MAIN: ', process.pid);
}
}
i odgovarajući app.ts:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { port } from './config';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableCors();
await app.listen(port);
}
bootstrap();
