fix: message queue injection issue (#6126)

This commit is contained in:
Jérémy M
2024-07-04 12:22:58 +02:00
committed by GitHub
parent 5b4d2d989a
commit 5df0ea6466
3 changed files with 36 additions and 31 deletions

View File

@ -25,7 +25,6 @@ import { MessageQueueMetadataAccessor } from './message-queue-metadata.accessor'
interface ProcessorGroup { interface ProcessorGroup {
instance: object; instance: object;
host: Module; host: Module;
processorName: string;
processMethodNames: string[]; processMethodNames: string[];
isRequestScoped: boolean; isRequestScoped: boolean;
} }
@ -78,7 +77,6 @@ export class MessageQueueExplorer implements OnModuleInit {
(acc, wrapper) => { (acc, wrapper) => {
const { instance, metatype } = wrapper; const { instance, metatype } = wrapper;
const methodNames = this.metadataScanner.getAllMethodNames(instance); const methodNames = this.metadataScanner.getAllMethodNames(instance);
const processorName = wrapper.name;
const { queueName } = const { queueName } =
this.metadataAccessor.getProcessorMetadata( this.metadataAccessor.getProcessorMetadata(
instance.constructor || metatype, instance.constructor || metatype,
@ -111,7 +109,6 @@ export class MessageQueueExplorer implements OnModuleInit {
acc[queueName].push({ acc[queueName].push({
instance, instance,
host: wrapper.host, host: wrapper.host,
processorName,
processMethodNames, processMethodNames,
isRequestScoped: !wrapper.isDependencyTreeStatic(), isRequestScoped: !wrapper.isDependencyTreeStatic(),
}); });
@ -140,11 +137,7 @@ export class MessageQueueExplorer implements OnModuleInit {
) { ) {
queue.work(async (job) => { queue.work(async (job) => {
for (const processorGroup of processorGroupCollection) { for (const processorGroup of processorGroupCollection) {
const { processorName } = processorGroup; await this.handleProcessor(processorGroup, job);
if (job.name === processorName) {
await this.handleProcessor(processorGroup, job);
}
} }
}, options); }, options);
} }
@ -153,16 +146,21 @@ export class MessageQueueExplorer implements OnModuleInit {
{ instance, host, processMethodNames, isRequestScoped }: ProcessorGroup, { instance, host, processMethodNames, isRequestScoped }: ProcessorGroup,
job: MessageQueueJob<MessageQueueJobData>, job: MessageQueueJob<MessageQueueJobData>,
) { ) {
const processMetadataCollection = new Map( const filteredProcessMethodNames = processMethodNames.filter(
processMethodNames.map((name) => { (processMethodName) => {
const metadata = this.metadataAccessor.getProcessMetadata( const metadata = this.metadataAccessor.getProcessMetadata(
instance[name], instance[processMethodName],
); );
return [name, metadata]; return metadata && job.name === metadata.jobName;
}), },
); );
// Return early if no matching methods found
if (filteredProcessMethodNames.length === 0) {
return;
}
if (isRequestScoped) { if (isRequestScoped) {
const contextId = createContextId(); const contextId = createContextId();
@ -187,29 +185,31 @@ export class MessageQueueExplorer implements OnModuleInit {
await this.invokeProcessMethods( await this.invokeProcessMethods(
contextInstance, contextInstance,
processMetadataCollection, filteredProcessMethodNames,
job, job,
); );
} else { } else {
await this.invokeProcessMethods(instance, processMetadataCollection, job); await this.invokeProcessMethods(
instance,
filteredProcessMethodNames,
job,
);
} }
} }
private async invokeProcessMethods( private async invokeProcessMethods(
instance: object, instance: object,
processMetadataCollection: Map<string, any>, processMethodNames: string[],
job: MessageQueueJob<MessageQueueJobData>, job: MessageQueueJob<MessageQueueJobData>,
) { ) {
for (const [methodName, metadata] of processMetadataCollection) { for (const processMethodName of processMethodNames) {
if (job.name === metadata?.jobName) { try {
try { await instance[processMethodName].call(instance, job.data);
await instance[methodName].call(instance, job.data); } catch (err) {
} catch (err) { if (!shouldFilterException(err)) {
if (!shouldFilterException(err)) { this.exceptionHandlerService.captureExceptions([err]);
this.exceptionHandlerService.captureExceptions([err]);
}
throw err;
} }
throw err;
} }
} }
} }

View File

@ -1,4 +1,4 @@
import { Inject, Injectable, Scope } from '@nestjs/common'; import { Inject, Injectable, Optional, Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core'; import { REQUEST } from '@nestjs/core';
import { EntitySchema } from 'typeorm'; import { EntitySchema } from 'typeorm';
@ -8,7 +8,9 @@ import { WorkspaceDatasourceFactory } from 'src/engine/twenty-orm/factories/work
@Injectable({ scope: Scope.REQUEST }) @Injectable({ scope: Scope.REQUEST })
export class ScopedWorkspaceDatasourceFactory { export class ScopedWorkspaceDatasourceFactory {
constructor( constructor(
@Inject(REQUEST) private readonly request: Request, @Optional()
@Inject(REQUEST)
private readonly request: Request | null,
private readonly workspaceDataSourceFactory: WorkspaceDatasourceFactory, private readonly workspaceDataSourceFactory: WorkspaceDatasourceFactory,
) {} ) {}

View File

@ -1,9 +1,8 @@
import { Injectable, Type } from '@nestjs/common'; import { Injectable, Optional, Type } from '@nestjs/common';
import { ObjectLiteral } from 'typeorm'; import { ObjectLiteral } from 'typeorm';
import { EntitySchemaFactory } from 'src/engine/twenty-orm/factories/entity-schema.factory'; import { EntitySchemaFactory } from 'src/engine/twenty-orm/factories/entity-schema.factory';
import { InjectWorkspaceDatasource } from 'src/engine/twenty-orm/decorators/inject-workspace-datasource.decorator';
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource'; import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository'; import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
import { WorkspaceDatasourceFactory } from 'src/engine/twenty-orm/factories/workspace-datasource.factory'; import { WorkspaceDatasourceFactory } from 'src/engine/twenty-orm/factories/workspace-datasource.factory';
@ -12,8 +11,8 @@ import { ObjectLiteralStorage } from 'src/engine/twenty-orm/storage/object-liter
@Injectable() @Injectable()
export class TwentyORMManager { export class TwentyORMManager {
constructor( constructor(
@InjectWorkspaceDatasource() @Optional()
private readonly workspaceDataSource: WorkspaceDataSource, private readonly workspaceDataSource: WorkspaceDataSource | null,
private readonly entitySchemaFactory: EntitySchemaFactory, private readonly entitySchemaFactory: EntitySchemaFactory,
private readonly workspaceDataSourceFactory: WorkspaceDatasourceFactory, private readonly workspaceDataSourceFactory: WorkspaceDatasourceFactory,
) {} ) {}
@ -23,6 +22,10 @@ export class TwentyORMManager {
): WorkspaceRepository<T> { ): WorkspaceRepository<T> {
const entitySchema = this.entitySchemaFactory.create(entityClass); const entitySchema = this.entitySchemaFactory.create(entityClass);
if (!this.workspaceDataSource) {
throw new Error('Workspace data source not found');
}
return this.workspaceDataSource.getRepository<T>(entitySchema); return this.workspaceDataSource.getRepository<T>(entitySchema);
} }