-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- create a workflow run every time a workflow is triggered in not_started status. This status will be helpful later for once workflows will be scheduled - update run status once workflow starts running - complete status once the workflow finished running - add a failed status if an error occurs
- Loading branch information
Showing
17 changed files
with
390 additions
and
45 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
124 changes: 124 additions & 0 deletions
124
...enty-server/src/modules/workflow/common/standard-objects/workflow-run.workspace-entity.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
import { Relation } from 'src/engine/workspace-manager/workspace-sync-metadata/interfaces/relation.interface'; | ||
|
||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum'; | ||
import { | ||
ActorMetadata, | ||
FieldActorSource, | ||
} from 'src/engine/metadata-modules/field-metadata/composite-types/actor.composite-type'; | ||
import { FieldMetadataType } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; | ||
import { RelationMetadataType } from 'src/engine/metadata-modules/relation-metadata/relation-metadata.entity'; | ||
import { BaseWorkspaceEntity } from 'src/engine/twenty-orm/base.workspace-entity'; | ||
import { WorkspaceEntity } from 'src/engine/twenty-orm/decorators/workspace-entity.decorator'; | ||
import { WorkspaceField } from 'src/engine/twenty-orm/decorators/workspace-field.decorator'; | ||
import { WorkspaceGate } from 'src/engine/twenty-orm/decorators/workspace-gate.decorator'; | ||
import { WorkspaceIsNullable } from 'src/engine/twenty-orm/decorators/workspace-is-nullable.decorator'; | ||
import { WorkspaceIsSystem } from 'src/engine/twenty-orm/decorators/workspace-is-system.decorator'; | ||
import { WorkspaceJoinColumn } from 'src/engine/twenty-orm/decorators/workspace-join-column.decorator'; | ||
import { WorkspaceRelation } from 'src/engine/twenty-orm/decorators/workspace-relation.decorator'; | ||
import { WORKFLOW_RUN_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; | ||
import { STANDARD_OBJECT_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-object-ids'; | ||
import { WorkflowVersionWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity'; | ||
|
||
export enum WorkflowRunStatus { | ||
NOT_STARTED = 'NOT_STARTED', | ||
RUNNING = 'RUNNING', | ||
COMPLETED = 'COMPLETED', | ||
FAILED = 'FAILED', | ||
} | ||
|
||
@WorkspaceEntity({ | ||
standardId: STANDARD_OBJECT_IDS.workflowRun, | ||
namePlural: 'workflowRuns', | ||
labelSingular: 'workflowRun', | ||
labelPlural: 'WorkflowRuns', | ||
description: 'A workflow run', | ||
}) | ||
@WorkspaceGate({ | ||
featureFlag: FeatureFlagKey.IsWorkflowEnabled, | ||
}) | ||
@WorkspaceIsSystem() | ||
export class WorkflowRunWorkspaceEntity extends BaseWorkspaceEntity { | ||
@WorkspaceField({ | ||
standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.startedAt, | ||
type: FieldMetadataType.DATE_TIME, | ||
label: 'Workflow run started at', | ||
description: 'Workflow run started at', | ||
icon: 'IconHistory', | ||
}) | ||
@WorkspaceIsNullable() | ||
startedAt: string | null; | ||
|
||
@WorkspaceField({ | ||
standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.endedAt, | ||
type: FieldMetadataType.DATE_TIME, | ||
label: 'Workflow run ended at', | ||
description: 'Workflow run ended at', | ||
icon: 'IconHistory', | ||
}) | ||
@WorkspaceIsNullable() | ||
endedAt: string | null; | ||
|
||
@WorkspaceField({ | ||
standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.status, | ||
type: FieldMetadataType.SELECT, | ||
label: 'Workflow run status', | ||
description: 'Workflow run status', | ||
icon: 'IconHistory', | ||
options: [ | ||
{ | ||
value: WorkflowRunStatus.NOT_STARTED, | ||
label: 'Not started', | ||
position: 0, | ||
color: 'grey', | ||
}, | ||
{ | ||
value: WorkflowRunStatus.RUNNING, | ||
label: 'Running', | ||
position: 1, | ||
color: 'yellow', | ||
}, | ||
{ | ||
value: WorkflowRunStatus.COMPLETED, | ||
label: 'Completed', | ||
position: 2, | ||
color: 'green', | ||
}, | ||
{ | ||
value: WorkflowRunStatus.FAILED, | ||
label: 'Failed', | ||
position: 3, | ||
color: 'red', | ||
}, | ||
], | ||
defaultValue: "'NOT_STARTED'", | ||
}) | ||
status: WorkflowRunStatus; | ||
|
||
@WorkspaceField({ | ||
standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.createdBy, | ||
type: FieldMetadataType.ACTOR, | ||
label: 'Created by', | ||
icon: 'IconCreativeCommonsSa', | ||
description: 'The creator of the record', | ||
defaultValue: { | ||
source: `'${FieldActorSource.MANUAL}'`, | ||
name: "''", | ||
}, | ||
}) | ||
createdBy: ActorMetadata; | ||
|
||
// Relations | ||
@WorkspaceRelation({ | ||
standardId: WORKFLOW_RUN_STANDARD_FIELD_IDS.workflowVersion, | ||
type: RelationMetadataType.MANY_TO_ONE, | ||
label: 'Workflow', | ||
description: 'WorkflowVersion workflow', | ||
icon: 'IconVersions', | ||
inverseSideTarget: () => WorkflowVersionWorkspaceEntity, | ||
inverseSideFieldKey: 'runs', | ||
}) | ||
workflowVersion: Relation<WorkflowVersionWorkspaceEntity>; | ||
|
||
@WorkspaceJoinColumn('workflowVersion') | ||
workflowVersionId: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
packages/twenty-server/src/modules/workflow/workflow-runner/workflow-runner.exception.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { CustomException } from 'src/utils/custom-exception'; | ||
|
||
export class WorkflowRunnerException extends CustomException { | ||
constructor(message: string, code: string) { | ||
super(message, code); | ||
} | ||
} | ||
|
||
export enum WorkflowRunnerExceptionCode { | ||
WORKFLOW_FAILED = 'WORKFLOW_FAILED', | ||
} |
56 changes: 31 additions & 25 deletions
56
packages/twenty-server/src/modules/workflow/workflow-runner/workflow-runner.job.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,54 +1,60 @@ | ||
import { Scope } from '@nestjs/common'; | ||
|
||
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator'; | ||
import { Processor } from 'src/engine/integrations/message-queue/decorators/processor.decorator'; | ||
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants'; | ||
import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; | ||
import { WorkflowWorkspaceEntity } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity'; | ||
import { WorkflowRunStatus } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity'; | ||
import { WorkflowCommonService } from 'src/modules/workflow/common/workflow-common.services'; | ||
import { WorkflowRunnerService } from 'src/modules/workflow/workflow-runner/workflow-runner.service'; | ||
import { WorkflowStatusWorkspaceService } from 'src/modules/workflow/workflow-status/workflow-status.workspace-service'; | ||
|
||
export type RunWorkflowJobData = { | ||
workspaceId: string; | ||
workflowId: string; | ||
workflowVersionId: string; | ||
workflowRunId: string; | ||
payload: object; | ||
}; | ||
|
||
@Processor(MessageQueue.workflowQueue) | ||
@Processor({ queueName: MessageQueue.workflowQueue, scope: Scope.REQUEST }) | ||
export class WorkflowRunnerJob { | ||
constructor( | ||
private readonly workflowCommonService: WorkflowCommonService, | ||
private readonly workflowRunnerService: WorkflowRunnerService, | ||
private readonly twentyORMGlobalManager: TwentyORMGlobalManager, | ||
private readonly workflowStatusWorkspaceService: WorkflowStatusWorkspaceService, | ||
) {} | ||
|
||
@Process(WorkflowRunnerJob.name) | ||
async handle({ | ||
workspaceId, | ||
workflowId, | ||
workflowVersionId, | ||
workflowRunId, | ||
payload, | ||
}: RunWorkflowJobData): Promise<void> { | ||
const workflowRepository = | ||
await this.twentyORMGlobalManager.getRepositoryForWorkspace<WorkflowWorkspaceEntity>( | ||
workspaceId, | ||
'workflow', | ||
); | ||
|
||
const workflow = await workflowRepository.findOneByOrFail({ | ||
id: workflowId, | ||
}); | ||
|
||
if (!workflow.publishedVersionId) { | ||
throw new Error('Workflow has no published version'); | ||
} | ||
await this.workflowStatusWorkspaceService.startWorkflowRun(workflowRunId); | ||
|
||
const workflowVersion = await this.workflowCommonService.getWorkflowVersion( | ||
workspaceId, | ||
workflow.publishedVersionId, | ||
workflowVersionId, | ||
); | ||
|
||
await this.workflowRunnerService.run({ | ||
action: workflowVersion.trigger.nextAction, | ||
workspaceId, | ||
payload, | ||
}); | ||
try { | ||
await this.workflowRunnerService.run({ | ||
action: workflowVersion.trigger.nextAction, | ||
workspaceId, | ||
payload, | ||
}); | ||
|
||
await this.workflowStatusWorkspaceService.endWorkflowRun( | ||
workflowRunId, | ||
WorkflowRunStatus.COMPLETED, | ||
); | ||
} catch (error) { | ||
await this.workflowStatusWorkspaceService.endWorkflowRun( | ||
workflowRunId, | ||
WorkflowRunStatus.FAILED, | ||
); | ||
|
||
throw error; | ||
} | ||
} | ||
} |
11 changes: 8 additions & 3 deletions
11
packages/twenty-server/src/modules/workflow/workflow-runner/workflow-runner.module.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.