From 45c49e89f28123ef622fc1c07253bae94fd74875 Mon Sep 17 00:00:00 2001 From: "Carlos R. L. Rodrigues" <37986729+carlos-r-l-rodrigues@users.noreply.github.com> Date: Thu, 28 Mar 2024 14:51:29 -0300 Subject: [PATCH] chore(workflows-sdk): add idempotencyKey to shared context (#6860) --- .changeset/olive-cows-do.md | 6 +++ .../src/workflow/workflow-manager.ts | 8 +++- packages/types/src/shared-context.ts | 5 +++ .../src/utils/composer/create-step.ts | 41 ++++++++++++------- .../workflows-sdk/src/utils/composer/hook.ts | 30 ++++++++------ 5 files changed, 61 insertions(+), 29 deletions(-) create mode 100644 .changeset/olive-cows-do.md diff --git a/.changeset/olive-cows-do.md b/.changeset/olive-cows-do.md new file mode 100644 index 0000000000..b1940e6461 --- /dev/null +++ b/.changeset/olive-cows-do.md @@ -0,0 +1,6 @@ +--- +"@medusajs/workflows-sdk": patch +"@medusajs/types": patch +--- + +Add workflow idempotencyKey to shared context diff --git a/packages/orchestration/src/workflow/workflow-manager.ts b/packages/orchestration/src/workflow/workflow-manager.ts index d5822a0e82..fa75f8a6e3 100644 --- a/packages/orchestration/src/workflow/workflow-manager.ts +++ b/packages/orchestration/src/workflow/workflow-manager.ts @@ -32,7 +32,7 @@ export type WorkflowHandler = Map< { invoke: WorkflowStepHandler; compensate?: WorkflowStepHandler } > -export type WorkflowStepHandler = (args: { +export type WorkflowStepHandlerArguments = { container: MedusaContainer payload: unknown invoke: { [actions: string]: unknown } @@ -40,7 +40,11 @@ export type WorkflowStepHandler = (args: { metadata: TransactionMetadata transaction: DistributedTransaction context?: Context -}) => unknown +} + +export type WorkflowStepHandler = ( + args: WorkflowStepHandlerArguments +) => unknown export class WorkflowManager { protected static workflows: Map = new Map() diff --git a/packages/types/src/shared-context.ts b/packages/types/src/shared-context.ts index 57c556d4a1..ce9302645d 100644 --- a/packages/types/src/shared-context.ts +++ b/packages/types/src/shared-context.ts @@ -76,4 +76,9 @@ export type Context = { * A string indicating the ID of the current request. */ requestId?: string + + /** + * A string indicating the idempotencyKey of the current workflow execution. + */ + idempotencyKey?: string } diff --git a/packages/workflows-sdk/src/utils/composer/create-step.ts b/packages/workflows-sdk/src/utils/composer/create-step.ts index 83c078f8c3..7df37e6f2f 100644 --- a/packages/workflows-sdk/src/utils/composer/create-step.ts +++ b/packages/workflows-sdk/src/utils/composer/create-step.ts @@ -1,6 +1,7 @@ import { TransactionStepsDefinition, WorkflowManager, + WorkflowStepHandlerArguments, } from "@medusajs/orchestration" import { OrchestrationUtils, deepCopy, isString } from "@medusajs/utils" import { ulid } from "ulid" @@ -120,16 +121,20 @@ function applyStep< } const handler = { - invoke: async (transactionContext) => { + invoke: async (transactionContext: WorkflowStepHandlerArguments) => { + const metadata = transactionContext.metadata + const idempotencyKey = metadata.idempotency_key + + transactionContext.context!.idempotencyKey = idempotencyKey const executionContext: StepExecutionContext = { - workflowId: transactionContext.model_id, - stepName: transactionContext.action, + workflowId: metadata.model_id, + stepName: metadata.action, action: "invoke", - idempotencyKey: transactionContext.idempotency_key, - attempt: transactionContext.attempt, + idempotencyKey, + attempt: metadata.attempt, container: transactionContext.container, - metadata: transactionContext.metadata, - context: transactionContext.context, + metadata, + context: transactionContext.context!, } const argInput = input @@ -151,19 +156,25 @@ function applyStep< } }, compensate: compensateFn - ? async (transactionContext) => { + ? async (transactionContext: WorkflowStepHandlerArguments) => { + const metadata = transactionContext.metadata + const idempotencyKey = metadata.idempotency_key + + transactionContext.context!.idempotencyKey = idempotencyKey + const executionContext: StepExecutionContext = { - workflowId: transactionContext.model_id, - stepName: transactionContext.action, + workflowId: metadata.model_id, + stepName: metadata.action, action: "compensate", - idempotencyKey: transactionContext.idempotency_key, - attempt: transactionContext.attempt, + idempotencyKey, + attempt: metadata.attempt, container: transactionContext.container, - metadata: transactionContext.metadata, - context: transactionContext.context, + metadata, + context: transactionContext.context!, } - const stepOutput = transactionContext.invoke[stepName]?.output + const stepOutput = (transactionContext.invoke[stepName] as any) + ?.output const invokeResult = stepOutput?.__type === OrchestrationUtils.SymbolWorkflowStepResponse diff --git a/packages/workflows-sdk/src/utils/composer/hook.ts b/packages/workflows-sdk/src/utils/composer/hook.ts index 1576a08a1d..952ec0f866 100644 --- a/packages/workflows-sdk/src/utils/composer/hook.ts +++ b/packages/workflows-sdk/src/utils/composer/hook.ts @@ -1,4 +1,5 @@ -import { OrchestrationUtils } from "@medusajs/utils" +import { WorkflowStepHandlerArguments } from "@medusajs/orchestration" +import { OrchestrationUtils, deepCopy } from "@medusajs/utils" import { resolveValue } from "./helpers" import { CreateWorkflowComposerContext, @@ -108,22 +109,27 @@ export function hook( return hookBinder(name, function (context) { return { - __value: async function (transactionContext) { + __value: async function ( + transactionContext: WorkflowStepHandlerArguments + ) { + const metadata = transactionContext.metadata + const idempotencyKey = metadata.idempotency_key + + transactionContext.context!.idempotencyKey = idempotencyKey + const executionContext: StepExecutionContext = { - workflowId: transactionContext.model_id, - stepName: transactionContext.action, - action: transactionContext.action_type, - idempotencyKey: transactionContext.idempotency_key, - attempt: transactionContext.attempt, + workflowId: metadata.model_id, + stepName: metadata.action, + action: metadata.action_type, + idempotencyKey, + attempt: metadata.attempt, container: transactionContext.container, - metadata: transactionContext.metadata, - context: transactionContext.context, + metadata, + context: transactionContext.context!, } const allValues = await resolveValue(value, transactionContext) - const stepValue = allValues - ? JSON.parse(JSON.stringify(allValues)) - : allValues + const stepValue = allValues ? deepCopy(allValues) : allValues let finalResult const functions = context.hooksCallback_[name]