8725 workflow avoid serverless function autosave errors (#8916)
See issue #8725 - Build function asynchronously using a job - prevent useless builds - run promises simultaneously Todo: - fix outputSchema computing
This commit is contained in:
@ -0,0 +1,52 @@
|
||||
import { Scope } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
|
||||
import { Repository } from 'typeorm';
|
||||
|
||||
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
import { Process } from 'src/engine/core-modules/message-queue/decorators/process.decorator';
|
||||
import { ServerlessService } from 'src/engine/core-modules/serverless/serverless.service';
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { isDefined } from 'src/utils/is-defined';
|
||||
|
||||
export type BuildServerlessFunctionBatchEvent = {
|
||||
serverlessFunctions: {
|
||||
serverlessFunctionId: string;
|
||||
serverlessFunctionVersion: string;
|
||||
}[];
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
@Processor({
|
||||
queueName: MessageQueue.serverlessFunctionQueue,
|
||||
scope: Scope.REQUEST,
|
||||
})
|
||||
export class BuildServerlessFunctionJob {
|
||||
constructor(
|
||||
@InjectRepository(ServerlessFunctionEntity, 'metadata')
|
||||
private readonly serverlessFunctionRepository: Repository<ServerlessFunctionEntity>,
|
||||
private readonly serverlessService: ServerlessService,
|
||||
) {}
|
||||
|
||||
@Process(BuildServerlessFunctionJob.name)
|
||||
async handle(batchEvent: BuildServerlessFunctionBatchEvent): Promise<void> {
|
||||
for (const {
|
||||
serverlessFunctionId,
|
||||
serverlessFunctionVersion,
|
||||
} of batchEvent.serverlessFunctions) {
|
||||
const serverlessFunction =
|
||||
await this.serverlessFunctionRepository.findOneBy({
|
||||
id: serverlessFunctionId,
|
||||
workspaceId: batchEvent.workspaceId,
|
||||
});
|
||||
|
||||
if (isDefined(serverlessFunction)) {
|
||||
await this.serverlessService.build(
|
||||
serverlessFunction,
|
||||
serverlessFunctionVersion,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
import { Scope } from '@nestjs/common';
|
||||
|
||||
import { Processor } from 'src/engine/core-modules/message-queue/decorators/processor.decorator';
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||
import { Process } from 'src/engine/core-modules/message-queue/decorators/process.decorator';
|
||||
|
||||
export type DeleteServerlessFunctionBatchEvent = {
|
||||
ids: string[];
|
||||
workspaceId: string;
|
||||
};
|
||||
|
||||
@Processor({
|
||||
queueName: MessageQueue.serverlessFunctionQueue,
|
||||
scope: Scope.REQUEST,
|
||||
})
|
||||
export class DeleteServerlessFunctionJob {
|
||||
constructor(
|
||||
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||
) {}
|
||||
|
||||
@Process(DeleteServerlessFunctionJob.name)
|
||||
async handle(batchEvent: DeleteServerlessFunctionBatchEvent): Promise<void> {
|
||||
await Promise.all(
|
||||
batchEvent.ids.map((id) =>
|
||||
this.serverlessFunctionService.deleteOneServerlessFunction(
|
||||
id,
|
||||
batchEvent.workspaceId,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.mod
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { ServerlessFunctionResolver } from 'src/engine/metadata-modules/serverless-function/serverless-function.resolver';
|
||||
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||
import { BuildServerlessFunctionJob } from 'src/engine/metadata-modules/serverless-function/jobs/build-serverless-function.job';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@ -21,7 +22,11 @@ import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverles
|
||||
ThrottlerModule,
|
||||
AnalyticsModule,
|
||||
],
|
||||
providers: [ServerlessFunctionService, ServerlessFunctionResolver],
|
||||
providers: [
|
||||
ServerlessFunctionService,
|
||||
ServerlessFunctionResolver,
|
||||
BuildServerlessFunctionJob,
|
||||
],
|
||||
exports: [ServerlessFunctionService],
|
||||
})
|
||||
export class ServerlessFunctionModule {}
|
||||
|
||||
@ -32,6 +32,13 @@ import {
|
||||
} from 'src/engine/metadata-modules/serverless-function/serverless-function.exception';
|
||||
import { isDefined } from 'src/utils/is-defined';
|
||||
import { getLayerDependencies } from 'src/engine/core-modules/serverless/drivers/utils/get-last-layer-dependencies';
|
||||
import { InjectMessageQueue } from 'src/engine/core-modules/message-queue/decorators/message-queue.decorator';
|
||||
import { MessageQueue } from 'src/engine/core-modules/message-queue/message-queue.constants';
|
||||
import { MessageQueueService } from 'src/engine/core-modules/message-queue/services/message-queue.service';
|
||||
import {
|
||||
BuildServerlessFunctionBatchEvent,
|
||||
BuildServerlessFunctionJob,
|
||||
} from 'src/engine/metadata-modules/serverless-function/jobs/build-serverless-function.job';
|
||||
|
||||
@Injectable()
|
||||
export class ServerlessFunctionService {
|
||||
@ -43,6 +50,8 @@ export class ServerlessFunctionService {
|
||||
private readonly throttlerService: ThrottlerService,
|
||||
private readonly environmentService: EnvironmentService,
|
||||
private readonly analyticsService: AnalyticsService,
|
||||
@InjectMessageQueue(MessageQueue.serverlessFunctionQueue)
|
||||
private readonly messageQueueService: MessageQueueService,
|
||||
) {}
|
||||
|
||||
async findManyServerlessFunctions(where) {
|
||||
@ -263,7 +272,11 @@ export class ServerlessFunctionService {
|
||||
});
|
||||
}
|
||||
|
||||
await this.serverlessService.build(existingServerlessFunction, 'draft');
|
||||
await this.buildServerlessFunction({
|
||||
serverlessFunctionId: existingServerlessFunction.id,
|
||||
serverlessFunctionVersion: 'draft',
|
||||
workspaceId,
|
||||
});
|
||||
await this.serverlessFunctionRepository.update(
|
||||
existingServerlessFunction.id,
|
||||
{
|
||||
@ -330,7 +343,11 @@ export class ServerlessFunctionService {
|
||||
});
|
||||
}
|
||||
|
||||
await this.serverlessService.build(createdServerlessFunction, 'draft');
|
||||
await this.buildServerlessFunction({
|
||||
serverlessFunctionId: createdServerlessFunction.id,
|
||||
serverlessFunctionVersion: 'draft',
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
return this.serverlessFunctionRepository.findOneBy({
|
||||
id: createdServerlessFunction.id,
|
||||
@ -351,4 +368,25 @@ export class ServerlessFunctionService {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async buildServerlessFunction({
|
||||
serverlessFunctionId,
|
||||
serverlessFunctionVersion,
|
||||
workspaceId,
|
||||
}: {
|
||||
serverlessFunctionId: string;
|
||||
serverlessFunctionVersion: string;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
await this.messageQueueService.add<BuildServerlessFunctionBatchEvent>(
|
||||
BuildServerlessFunctionJob.name,
|
||||
{
|
||||
serverlessFunctions: [
|
||||
{ serverlessFunctionId, serverlessFunctionVersion },
|
||||
],
|
||||
workspaceId,
|
||||
},
|
||||
{ id: `${serverlessFunctionId}-${serverlessFunctionVersion}` },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user