Store output step by step (#10101)

- add context field
- store it with the output after each step execution
This commit is contained in:
Thomas Trompette
2025-02-10 11:27:15 +01:00
committed by GitHub
parent c908a687fb
commit e70e69cf94
9 changed files with 171 additions and 62 deletions

View File

@ -12,7 +12,7 @@ import {
WorkflowRunException,
WorkflowRunExceptionCode,
} from 'src/modules/workflow/workflow-runner/exceptions/workflow-run.exception';
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workspace-services/workflow-run.workspace-service';
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.workspace-service';
export type RunWorkflowJobData = {
workspaceId: string;
@ -38,7 +38,14 @@ export class RunWorkflowJob {
workflowRunId,
payload,
}: RunWorkflowJobData): Promise<void> {
await this.workflowRunWorkspaceService.startWorkflowRun(workflowRunId);
const context = {
trigger: payload,
};
await this.workflowRunWorkspaceService.startWorkflowRun({
workflowRunId,
context,
});
try {
const workflowVersion =
@ -48,35 +55,27 @@ export class RunWorkflowJob {
await this.throttleExecution(workflowVersion.workflowId);
const { steps, status } =
await this.workflowExecutorWorkspaceService.execute({
currentStepIndex: 0,
steps: workflowVersion.steps || [],
context: {
trigger: payload,
},
output: {
steps: {},
status: WorkflowRunStatus.RUNNING,
},
});
const { status } = await this.workflowExecutorWorkspaceService.execute({
workflowRunId,
currentStepIndex: 0,
steps: workflowVersion.steps || [],
context,
workflowExecutorOutput: {
steps: {},
status: WorkflowRunStatus.RUNNING,
},
});
await this.workflowRunWorkspaceService.endWorkflowRun(
await this.workflowRunWorkspaceService.endWorkflowRun({
workflowRunId,
status,
{
steps,
},
);
});
} catch (error) {
await this.workflowRunWorkspaceService.endWorkflowRun(
await this.workflowRunWorkspaceService.endWorkflowRun({
workflowRunId,
WorkflowRunStatus.FAILED,
{
steps: {},
error: error.message,
},
);
status: WorkflowRunStatus.FAILED,
error: error.message,
});
}
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.workspace-service';
@Module({
imports: [WorkflowCommonModule],
providers: [WorkflowRunWorkspaceService],
exports: [WorkflowRunWorkspaceService],
})
export class WorkflowRunModule {}

View File

@ -20,7 +20,13 @@ export class WorkflowRunWorkspaceService {
private readonly workflowCommonWorkspaceService: WorkflowCommonWorkspaceService,
) {}
async createWorkflowRun(workflowVersionId: string, createdBy: ActorMetadata) {
async createWorkflowRun({
workflowVersionId,
createdBy,
}: {
workflowVersionId: string;
createdBy: ActorMetadata;
}) {
const workflowRunRepository =
await this.twentyORMManager.getRepository<WorkflowRunWorkspaceEntity>(
'workflowRun',
@ -42,7 +48,13 @@ export class WorkflowRunWorkspaceService {
).id;
}
async startWorkflowRun(workflowRunId: string) {
async startWorkflowRun({
workflowRunId,
context,
}: {
workflowRunId: string;
context: Record<string, any>;
}) {
const workflowRunRepository =
await this.twentyORMManager.getRepository<WorkflowRunWorkspaceEntity>(
'workflowRun',
@ -69,14 +81,19 @@ export class WorkflowRunWorkspaceService {
return workflowRunRepository.update(workflowRunToUpdate.id, {
status: WorkflowRunStatus.RUNNING,
startedAt: new Date().toISOString(),
context,
});
}
async endWorkflowRun(
workflowRunId: string,
status: WorkflowRunStatus,
output: WorkflowRunOutput,
) {
async endWorkflowRun({
workflowRunId,
status,
error,
}: {
workflowRunId: string;
status: WorkflowRunStatus;
error?: string;
}) {
const workflowRunRepository =
await this.twentyORMManager.getRepository<WorkflowRunWorkspaceEntity>(
'workflowRun',
@ -102,8 +119,42 @@ export class WorkflowRunWorkspaceService {
return workflowRunRepository.update(workflowRunToUpdate.id, {
status,
output,
endedAt: new Date().toISOString(),
output: {
...(workflowRunToUpdate.output ?? {}),
error,
},
});
}
async saveWorkflowRunState({
workflowRunId,
output,
context,
}: {
workflowRunId: string;
output: WorkflowRunOutput;
context: Record<string, any>;
}) {
const workflowRunRepository =
await this.twentyORMManager.getRepository<WorkflowRunWorkspaceEntity>(
'workflowRun',
);
const workflowRunToUpdate = await workflowRunRepository.findOneBy({
id: workflowRunId,
});
if (!workflowRunToUpdate) {
throw new WorkflowRunException(
'No workflow run to save',
WorkflowRunExceptionCode.WORKFLOW_RUN_NOT_FOUND,
);
}
return workflowRunRepository.update(workflowRunId, {
output,
context,
});
}
}

View File

@ -5,7 +5,7 @@ import { ThrottlerModule } from 'src/engine/core-modules/throttler/throttler.mod
import { WorkflowCommonModule } from 'src/modules/workflow/common/workflow-common.module';
import { WorkflowExecutorModule } from 'src/modules/workflow/workflow-executor/workflow-executor.module';
import { RunWorkflowJob } from 'src/modules/workflow/workflow-runner/jobs/run-workflow.job';
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workspace-services/workflow-run.workspace-service';
import { WorkflowRunModule } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.module';
import { WorkflowRunnerWorkspaceService } from 'src/modules/workflow/workflow-runner/workspace-services/workflow-runner.workspace-service';
@Module({
@ -14,12 +14,9 @@ import { WorkflowRunnerWorkspaceService } from 'src/modules/workflow/workflow-ru
WorkflowExecutorModule,
ThrottlerModule,
BillingModule,
WorkflowRunModule,
],
providers: [
WorkflowRunnerWorkspaceService,
WorkflowRunWorkspaceService,
RunWorkflowJob,
],
providers: [WorkflowRunnerWorkspaceService, RunWorkflowJob],
exports: [WorkflowRunnerWorkspaceService],
})
export class WorkflowRunnerModule {}

View File

@ -9,7 +9,7 @@ import {
RunWorkflowJob,
RunWorkflowJobData,
} from 'src/modules/workflow/workflow-runner/jobs/run-workflow.job';
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workspace-services/workflow-run.workspace-service';
import { WorkflowRunWorkspaceService } from 'src/modules/workflow/workflow-runner/workflow-run/workflow-run.workspace-service';
@Injectable()
export class WorkflowRunnerWorkspaceService {
@ -36,10 +36,10 @@ export class WorkflowRunnerWorkspaceService {
);
}
const workflowRunId =
await this.workflowRunWorkspaceService.createWorkflowRun(
await this.workflowRunWorkspaceService.createWorkflowRun({
workflowVersionId,
source,
);
createdBy: source,
});
await this.messageQueueService.add<RunWorkflowJobData>(
RunWorkflowJob.name,