Remove serverless functions on soft delete (#9438)
Delete workflow versions serverless functions when soft delete workflow
This commit is contained in:
@ -122,10 +122,10 @@ export class ServerlessFunctionResolver {
|
|||||||
try {
|
try {
|
||||||
await this.checkFeatureFlag(workspaceId);
|
await this.checkFeatureFlag(workspaceId);
|
||||||
|
|
||||||
return await this.serverlessFunctionService.deleteOneServerlessFunction(
|
return await this.serverlessFunctionService.deleteOneServerlessFunction({
|
||||||
input.id,
|
id: input.id,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
serverlessFunctionGraphQLApiExceptionHandler(error);
|
serverlessFunctionGraphQLApiExceptionHandler(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -205,7 +205,15 @@ export class ServerlessFunctionService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteOneServerlessFunction(id: string, workspaceId: string) {
|
async deleteOneServerlessFunction({
|
||||||
|
id,
|
||||||
|
workspaceId,
|
||||||
|
isHardDeletion = true,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
workspaceId: string;
|
||||||
|
isHardDeletion?: boolean;
|
||||||
|
}) {
|
||||||
const existingServerlessFunction =
|
const existingServerlessFunction =
|
||||||
await this.serverlessFunctionRepository.findOneBy({
|
await this.serverlessFunctionRepository.findOneBy({
|
||||||
id,
|
id,
|
||||||
@ -219,16 +227,17 @@ export class ServerlessFunctionService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.serverlessFunctionRepository.delete(id);
|
if (isHardDeletion) {
|
||||||
|
await this.serverlessFunctionRepository.delete(id);
|
||||||
|
await this.fileStorageService.delete({
|
||||||
|
folderPath: getServerlessFolder({
|
||||||
|
serverlessFunction: existingServerlessFunction,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
await this.serverlessService.delete(existingServerlessFunction);
|
await this.serverlessService.delete(existingServerlessFunction);
|
||||||
|
|
||||||
await this.fileStorageService.delete({
|
|
||||||
folderPath: getServerlessFolder({
|
|
||||||
serverlessFunction: existingServerlessFunction,
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
|
|
||||||
return existingServerlessFunction;
|
return existingServerlessFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,12 +18,13 @@ export class WorkflowDeleteManyPostQueryHook
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(
|
async execute(
|
||||||
_authContext: AuthContext,
|
authContext: AuthContext,
|
||||||
_objectName: string,
|
_objectName: string,
|
||||||
payload: WorkflowWorkspaceEntity[],
|
payload: WorkflowWorkspaceEntity[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
this.workflowCommonWorkspaceService.cleanWorkflowsSubEntities(
|
this.workflowCommonWorkspaceService.cleanWorkflowsSubEntities(
|
||||||
payload.map((workflow) => workflow.id),
|
payload.map((workflow) => workflow.id),
|
||||||
|
authContext.workspace.id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,12 +18,13 @@ export class WorkflowDeleteOnePostQueryHook
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(
|
async execute(
|
||||||
_authContext: AuthContext,
|
authContext: AuthContext,
|
||||||
_objectName: string,
|
_objectName: string,
|
||||||
payload: WorkflowWorkspaceEntity[],
|
payload: WorkflowWorkspaceEntity[],
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
this.workflowCommonWorkspaceService.cleanWorkflowsSubEntities(
|
this.workflowCommonWorkspaceService.cleanWorkflowsSubEntities(
|
||||||
payload.map((workflow) => workflow.id),
|
payload.map((workflow) => workflow.id),
|
||||||
|
authContext.workspace.id,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,10 +25,12 @@ import { WorkflowVersionUpdateManyPreQueryHook } from 'src/modules/workflow/comm
|
|||||||
import { WorkflowVersionUpdateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-version-update-one.pre-query.hook';
|
import { WorkflowVersionUpdateOnePreQueryHook } from 'src/modules/workflow/common/query-hooks/workflow-version-update-one.pre-query.hook';
|
||||||
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
|
import { WorkflowCommonWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-common.workspace-service';
|
||||||
import { WorkflowVersionValidationWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-version-validation.workspace-service';
|
import { WorkflowVersionValidationWorkspaceService } from 'src/modules/workflow/common/workspace-services/workflow-version-validation.workspace-service';
|
||||||
|
import { ServerlessFunctionModule } from 'src/engine/metadata-modules/serverless-function/serverless-function.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
NestjsQueryTypeOrmModule.forFeature([ObjectMetadataEntity], 'metadata'),
|
||||||
|
ServerlessFunctionModule,
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
WorkflowCreateOnePreQueryHook,
|
WorkflowCreateOnePreQueryHook,
|
||||||
|
|||||||
@ -8,10 +8,16 @@ import {
|
|||||||
WorkflowTriggerException,
|
WorkflowTriggerException,
|
||||||
WorkflowTriggerExceptionCode,
|
WorkflowTriggerExceptionCode,
|
||||||
} from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
|
} from 'src/modules/workflow/workflow-trigger/exceptions/workflow-trigger.exception';
|
||||||
|
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
|
||||||
|
import { WorkflowActionType } from 'src/modules/workflow/workflow-executor/workflow-actions/types/workflow-action.type';
|
||||||
|
import { ServerlessFunctionService } from 'src/engine/metadata-modules/serverless-function/serverless-function.service';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class WorkflowCommonWorkspaceService {
|
export class WorkflowCommonWorkspaceService {
|
||||||
constructor(private readonly twentyORMManager: TwentyORMManager) {}
|
constructor(
|
||||||
|
private readonly twentyORMManager: TwentyORMManager,
|
||||||
|
private readonly serverlessFunctionService: ServerlessFunctionService,
|
||||||
|
) {}
|
||||||
|
|
||||||
async getWorkflowVersionOrFail(
|
async getWorkflowVersionOrFail(
|
||||||
workflowVersionId: string,
|
workflowVersionId: string,
|
||||||
@ -58,7 +64,10 @@ export class WorkflowCommonWorkspaceService {
|
|||||||
return { ...workflowVersion, trigger: workflowVersion.trigger };
|
return { ...workflowVersion, trigger: workflowVersion.trigger };
|
||||||
}
|
}
|
||||||
|
|
||||||
async cleanWorkflowsSubEntities(workflowIds: string[]): Promise<void> {
|
async cleanWorkflowsSubEntities(
|
||||||
|
workflowIds: string[],
|
||||||
|
workspaceId: string,
|
||||||
|
): Promise<void> {
|
||||||
const workflowVersionRepository =
|
const workflowVersionRepository =
|
||||||
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
await this.twentyORMManager.getRepository<WorkflowVersionWorkspaceEntity>(
|
||||||
'workflowVersion',
|
'workflowVersion',
|
||||||
@ -74,20 +83,48 @@ export class WorkflowCommonWorkspaceService {
|
|||||||
'workflowEventListener',
|
'workflowEventListener',
|
||||||
);
|
);
|
||||||
|
|
||||||
Promise.all(
|
workflowIds.forEach((workflowId) => {
|
||||||
workflowIds.map((workflowId) => {
|
workflowEventListenerRepository.softDelete({
|
||||||
workflowEventListenerRepository.softDelete({
|
workflowId,
|
||||||
workflowId,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
workflowRunRepository.softDelete({
|
workflowRunRepository.softDelete({
|
||||||
workflowId,
|
workflowId,
|
||||||
});
|
});
|
||||||
|
|
||||||
workflowVersionRepository.softDelete({
|
workflowVersionRepository.softDelete({
|
||||||
workflowId,
|
workflowId,
|
||||||
});
|
});
|
||||||
}),
|
|
||||||
);
|
this.deleteServerlessFunctions(
|
||||||
|
workflowVersionRepository,
|
||||||
|
workflowId,
|
||||||
|
workspaceId,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async deleteServerlessFunctions(
|
||||||
|
workflowVersionRepository: WorkspaceRepository<WorkflowVersionWorkspaceEntity>,
|
||||||
|
workflowId: string,
|
||||||
|
workspaceId: string,
|
||||||
|
) {
|
||||||
|
const workflowVersions = await workflowVersionRepository.find({
|
||||||
|
where: {
|
||||||
|
workflowId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
workflowVersions.forEach((workflowVersion) => {
|
||||||
|
workflowVersion.steps?.forEach(async (step) => {
|
||||||
|
if (step.type === WorkflowActionType.CODE) {
|
||||||
|
await this.serverlessFunctionService.deleteOneServerlessFunction({
|
||||||
|
id: step.settings.input.serverlessFunctionId,
|
||||||
|
workspaceId,
|
||||||
|
isHardDeletion: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -511,10 +511,10 @@ export class WorkflowVersionStepWorkspaceService {
|
|||||||
}) {
|
}) {
|
||||||
switch (step.type) {
|
switch (step.type) {
|
||||||
case WorkflowActionType.CODE: {
|
case WorkflowActionType.CODE: {
|
||||||
await this.serverlessFunctionService.deleteOneServerlessFunction(
|
await this.serverlessFunctionService.deleteOneServerlessFunction({
|
||||||
step.settings.input.serverlessFunctionId,
|
id: step.settings.input.serverlessFunctionId,
|
||||||
workspaceId,
|
workspaceId,
|
||||||
);
|
});
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user