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:
Adrien de Peretti
2023-12-19 10:38:27 +01:00
committed by GitHub
parent 1a2f513d53
commit 9cc787cac4
21 changed files with 255 additions and 92 deletions

View File

@@ -0,0 +1,15 @@
export class PermanentStepFailureError extends Error {
static isPermanentStepFailureError(
error: Error
): error is PermanentStepFailureError {
return (
error instanceof PermanentStepFailureError ||
error.name === "PermanentStepFailure"
)
}
constructor(message?: string) {
super(message)
this.name = "PermanentStepFailure"
}
}

View File

@@ -3,3 +3,4 @@ export * from "./transaction-orchestrator"
export * from "./transaction-step"
export * from "./distributed-transaction"
export * from "./orchestrator-builder"
export * from "./errors"

View File

@@ -13,6 +13,7 @@ import {
import { EventEmitter } from "events"
import { promiseAll } from "@medusajs/utils"
import { PermanentStepFailureError } from "./errors"
export type TransactionFlow = {
modelId: string
@@ -367,11 +368,23 @@ export class TransactionOrchestrator extends EventEmitter {
transaction.getContext()
)
const setStepFailure = async (
error: Error | any,
{ endRetry }: { endRetry?: boolean } = {}
) => {
return TransactionOrchestrator.setStepFailure(
transaction,
step,
error,
endRetry ? 0 : step.definition.maxRetries
)
}
if (!step.definition.async) {
execution.push(
transaction
.handler(step.definition.action + "", type, payload, transaction)
.then(async (response) => {
.then(async (response: any) => {
await TransactionOrchestrator.setStepSuccess(
transaction,
step,
@@ -379,12 +392,13 @@ export class TransactionOrchestrator extends EventEmitter {
)
})
.catch(async (error) => {
await TransactionOrchestrator.setStepFailure(
transaction,
step,
error,
step.definition.maxRetries
)
if (
PermanentStepFailureError.isPermanentStepFailureError(error)
) {
await setStepFailure(error, { endRetry: true })
return
}
await setStepFailure(error)
})
)
} else {
@@ -393,12 +407,13 @@ export class TransactionOrchestrator extends EventEmitter {
transaction
.handler(step.definition.action + "", type, payload, transaction)
.catch(async (error) => {
await TransactionOrchestrator.setStepFailure(
transaction,
step,
error,
step.definition.maxRetries
)
if (
PermanentStepFailureError.isPermanentStepFailureError(error)
) {
await setStepFailure(error, { endRetry: true })
return
}
await setStepFailure(error)
})
)
)