feat(workflows-sdk): Configurable retries upon step creation (#5728)
**What**
- Allow to create step that can be configured to have a max retry
- Step end retry mechanism on permanent failure
Also added an API to override a step configuration from within the createWorkflow
```ts
const step = createStep({ name: "step", maxRetries: 3 }, async (_, context) => {
return new StepResponse({ output: "output" })
})
const workflow = createWorkflow("workflow", function () {
const res = step().config({ maxRetries: 5 }) // This will override the original maxRetries of 3
})
```
**NOTE**
We can maybe find another name than config on the step workflow data to override the step config.
This commit is contained in:
committed by
GitHub
parent
1a2f513d53
commit
9cc787cac4
@@ -1,12 +1,4 @@
|
||||
import {
|
||||
resolveValue,
|
||||
StepResponse,
|
||||
SymbolMedusaWorkflowComposerContext,
|
||||
SymbolWorkflowStep,
|
||||
SymbolWorkflowStepBind,
|
||||
SymbolWorkflowStepResponse,
|
||||
SymbolWorkflowWorkflowData,
|
||||
} from "./helpers"
|
||||
import { resolveValue, StepResponse } from "./helpers"
|
||||
import {
|
||||
CreateWorkflowComposerContext,
|
||||
StepExecutionContext,
|
||||
@@ -15,6 +7,8 @@ import {
|
||||
WorkflowData,
|
||||
} from "./type"
|
||||
import { proxify } from "./helpers/proxy"
|
||||
import { TransactionStepsDefinition } from "@medusajs/orchestration"
|
||||
import { isString, OrchestrationUtils } from "@medusajs/utils"
|
||||
|
||||
/**
|
||||
* The type of invocation function passed to a step.
|
||||
@@ -75,6 +69,7 @@ interface ApplyStepOptions<
|
||||
TInvokeResultCompensateInput
|
||||
> {
|
||||
stepName: string
|
||||
stepConfig?: TransactionStepsDefinition
|
||||
input: TStepInputs
|
||||
invokeFn: InvokeFn<
|
||||
TInvokeInput,
|
||||
@@ -91,6 +86,7 @@ interface ApplyStepOptions<
|
||||
* This is where the inputs and context are passed to the underlying invoke and compensate function.
|
||||
*
|
||||
* @param stepName
|
||||
* @param stepConfig
|
||||
* @param input
|
||||
* @param invokeFn
|
||||
* @param compensateFn
|
||||
@@ -104,6 +100,7 @@ function applyStep<
|
||||
TInvokeResultCompensateInput
|
||||
>({
|
||||
stepName,
|
||||
stepConfig = {},
|
||||
input,
|
||||
invokeFn,
|
||||
compensateFn,
|
||||
@@ -135,12 +132,12 @@ function applyStep<
|
||||
)
|
||||
|
||||
const stepResponseJSON =
|
||||
stepResponse?.__type === SymbolWorkflowStepResponse
|
||||
stepResponse?.__type === OrchestrationUtils.SymbolWorkflowStepResponse
|
||||
? stepResponse.toJSON()
|
||||
: stepResponse
|
||||
|
||||
return {
|
||||
__type: SymbolWorkflowWorkflowData,
|
||||
__type: OrchestrationUtils.SymbolWorkflowWorkflowData,
|
||||
output: stepResponseJSON,
|
||||
}
|
||||
},
|
||||
@@ -154,7 +151,8 @@ function applyStep<
|
||||
|
||||
const stepOutput = transactionContext.invoke[stepName]?.output
|
||||
const invokeResult =
|
||||
stepOutput?.__type === SymbolWorkflowStepResponse
|
||||
stepOutput?.__type ===
|
||||
OrchestrationUtils.SymbolWorkflowStepResponse
|
||||
? stepOutput.compensateInput &&
|
||||
JSON.parse(JSON.stringify(stepOutput.compensateInput))
|
||||
: stepOutput && JSON.parse(JSON.stringify(stepOutput))
|
||||
@@ -168,14 +166,21 @@ function applyStep<
|
||||
: undefined,
|
||||
}
|
||||
|
||||
this.flow.addAction(stepName, {
|
||||
noCompensation: !compensateFn,
|
||||
})
|
||||
stepConfig!.noCompensation = !compensateFn
|
||||
|
||||
this.flow.addAction(stepName, stepConfig)
|
||||
this.handlers.set(stepName, handler)
|
||||
|
||||
const ret = {
|
||||
__type: SymbolWorkflowStep,
|
||||
__type: OrchestrationUtils.SymbolWorkflowStep,
|
||||
__step__: stepName,
|
||||
config: (config: Pick<TransactionStepsDefinition, "maxRetries">) => {
|
||||
this.flow.replaceAction(stepName, stepName, {
|
||||
...stepConfig,
|
||||
...config,
|
||||
})
|
||||
return proxify(ret)
|
||||
},
|
||||
}
|
||||
|
||||
return proxify(ret)
|
||||
@@ -236,9 +241,11 @@ export function createStep<
|
||||
TInvokeResultCompensateInput
|
||||
>(
|
||||
/**
|
||||
* The name of the step.
|
||||
* The name of the step or its configuration (currently support maxRetries).
|
||||
*/
|
||||
name: string,
|
||||
nameOrConfig:
|
||||
| string
|
||||
| ({ name: string } & Pick<TransactionStepsDefinition, "maxRetries">),
|
||||
/**
|
||||
* An invocation function that will be executed when the workflow is executed. The function must return an instance of {@link StepResponse}. The constructor of {@link StepResponse}
|
||||
* accepts the output of the step as a first argument, and optionally as a second argument the data to be passed to the compensation function as a parameter.
|
||||
@@ -256,12 +263,14 @@ export function createStep<
|
||||
*/
|
||||
compensateFn?: CompensateFn<TInvokeResultCompensateInput>
|
||||
): StepFunction<TInvokeInput, TInvokeResultOutput> {
|
||||
const stepName = name ?? invokeFn.name
|
||||
const stepName =
|
||||
(isString(nameOrConfig) ? nameOrConfig : nameOrConfig.name) ?? invokeFn.name
|
||||
const config = isString(nameOrConfig) ? {} : nameOrConfig
|
||||
|
||||
const returnFn = function (input: {
|
||||
[K in keyof TInvokeInput]: WorkflowData<TInvokeInput[K]>
|
||||
}): WorkflowData<TInvokeResultOutput> {
|
||||
if (!global[SymbolMedusaWorkflowComposerContext]) {
|
||||
if (!global[OrchestrationUtils.SymbolMedusaWorkflowComposerContext]) {
|
||||
throw new Error(
|
||||
"createStep must be used inside a createWorkflow definition"
|
||||
)
|
||||
@@ -269,7 +278,7 @@ export function createStep<
|
||||
|
||||
const stepBinder = (
|
||||
global[
|
||||
SymbolMedusaWorkflowComposerContext
|
||||
OrchestrationUtils.SymbolMedusaWorkflowComposerContext
|
||||
] as CreateWorkflowComposerContext
|
||||
).stepBinder
|
||||
|
||||
@@ -281,6 +290,7 @@ export function createStep<
|
||||
TInvokeResultCompensateInput
|
||||
>({
|
||||
stepName,
|
||||
stepConfig: config,
|
||||
input,
|
||||
invokeFn,
|
||||
compensateFn,
|
||||
@@ -288,7 +298,7 @@ export function createStep<
|
||||
)
|
||||
}
|
||||
|
||||
returnFn.__type = SymbolWorkflowStepBind
|
||||
returnFn.__type = OrchestrationUtils.SymbolWorkflowStepBind
|
||||
returnFn.__step__ = stepName
|
||||
|
||||
return returnFn as unknown as StepFunction<TInvokeInput, TInvokeResultOutput>
|
||||
|
||||
Reference in New Issue
Block a user