docs: rename Architectural Modules to Infrastructure Modules (#12212)
* docs: rename Architectural Modules to Infrastructure Modules * generate again
This commit is contained in:
@@ -0,0 +1,392 @@
|
||||
---
|
||||
sidebar_label: "Use Workflow Engine Module"
|
||||
tags:
|
||||
- workflow engine
|
||||
- server
|
||||
- how to
|
||||
---
|
||||
|
||||
import { TypeList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `How to Use the Workflow Engine Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this document, you’ll learn about the different methods in the Workflow Engine Module's service and how to use them.
|
||||
|
||||
---
|
||||
|
||||
## Resolve Workflow Engine Module's Service
|
||||
|
||||
In your workflow's step, you can resolve the Workflow Engine Module's service from the Medusa container:
|
||||
|
||||
```ts
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
import { createStep } from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
const step1 = createStep(
|
||||
"step-1",
|
||||
async ({}, { container }) => {
|
||||
const workflowEngineModuleService = container.resolve(
|
||||
Modules.WORKFLOW_ENGINE
|
||||
)
|
||||
|
||||
// TODO use workflowEngineModuleService
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
This will resolve the service of the configured Workflow Engine Module, which is the [In-Memory Workflow Engine Module](../in-memory/page.mdx) by default.
|
||||
|
||||
You can then use the Workflow Engine Module's service's methods in the step. The rest of this guide details these methods.
|
||||
|
||||
---
|
||||
|
||||
## setStepSuccess
|
||||
|
||||
This method sets an async step in a currently-executing [long-running workflow](!docs!/learn/fundamentals/workflows/long-running-workflow) as successful. The workflow will then continue to the next step.
|
||||
|
||||
### Example
|
||||
|
||||
```ts
|
||||
// other imports...
|
||||
import {
|
||||
TransactionHandlerType,
|
||||
} from "@medusajs/framework/utils"
|
||||
|
||||
await workflowEngineModuleService.setStepSuccess({
|
||||
idempotencyKey: {
|
||||
action: TransactionHandlerType.INVOKE,
|
||||
transactionId,
|
||||
stepId: "step-2",
|
||||
workflowId: "hello-world",
|
||||
},
|
||||
stepResponse: new StepResponse("Done!"),
|
||||
options: {
|
||||
container,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
<TypeList types={[
|
||||
{
|
||||
"name": "idempotencyKey",
|
||||
"type": "`object`",
|
||||
"description": "The details of the step to set as successful.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "action",
|
||||
"type": "`invoke` | `compensate`",
|
||||
"description": "If the step's compensation function is running, use `compensate`. Otherwise, use `invoke`.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "transactionId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow execution's transaction.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "stepId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the step to change its status. This is the first parameter passed to `createStep` when creating the step.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "workflowId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow. This is the first parameter passed to `createWorkflow` when creating the workflow.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stepResponse",
|
||||
"type": "`StepResponse`",
|
||||
"description": "Set the response of the step. This is similar to the response you return in a step's definition, but since the async step doesn't have a response, you set its response when changing its status.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"type": "`object`",
|
||||
"description": "Options to pass to the step.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "container",
|
||||
"type": "`Container`",
|
||||
"description": "An instance of the Medusa container.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="setStepSuccess"/>
|
||||
|
||||
---
|
||||
|
||||
## setStepFailure
|
||||
|
||||
This method sets an async step in a currently-executing [long-running workflow](!docs!/learn/fundamentals/workflows/long-running-workflow) as failed. The workflow will then stop executing and the compensation functions of the workflow's steps will be executed.
|
||||
|
||||
### Example
|
||||
|
||||
```ts
|
||||
// other imports...
|
||||
import {
|
||||
TransactionHandlerType,
|
||||
} from "@medusajs/framework/utils"
|
||||
|
||||
await workflowEngineModuleService.setStepFailure({
|
||||
idempotencyKey: {
|
||||
action: TransactionHandlerType.INVOKE,
|
||||
transactionId,
|
||||
stepId: "step-2",
|
||||
workflowId: "hello-world",
|
||||
},
|
||||
stepResponse: new StepResponse("Failed!"),
|
||||
options: {
|
||||
container,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
<TypeList types={[
|
||||
{
|
||||
"name": "idempotencyKey",
|
||||
"type": "`object`",
|
||||
"description": "The details of the step to set as failed.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "action",
|
||||
"type": "`invoke` | `compensate`",
|
||||
"description": "If the step's compensation function is running, use `compensate`. Otherwise, use `invoke`.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "transactionId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow execution's transaction.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "stepId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the step to change its status. This is the first parameter passed to `createStep` when creating the step.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "workflowId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow. This is the first parameter passed to `createWorkflow` when creating the workflow.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "stepResponse",
|
||||
"type": "`StepResponse`",
|
||||
"description": "Set the response of the step. This is similar to the response you return in a step's definition, but since the async step doesn't have a response, you set its response when changing its status.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "options",
|
||||
"type": "`object`",
|
||||
"description": "Options to pass to the step.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "container",
|
||||
"type": "`Container`",
|
||||
"description": "An instance of the Medusa container.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="setStepFailure"/>
|
||||
|
||||
---
|
||||
|
||||
## subscribe
|
||||
|
||||
This method subscribes to a workflow's events. You can use this method to listen to a [long-running workflow](!docs!/learn/fundamentals/workflows/long-running-workflow)'s events and retrieve its result once it's done executing.
|
||||
|
||||
Refer to the [Long-Running Workflows](!docs!/learn/fundamentals/workflows/long-running-workflow#access-long-running-workflow-status-and-result) documentation to learn more.
|
||||
|
||||
### Example
|
||||
|
||||
```ts
|
||||
const { transaction } = await helloWorldWorkflow(container).run()
|
||||
|
||||
const subscriptionOptions = {
|
||||
workflowId: "hello-world",
|
||||
transactionId: transaction.transactionId,
|
||||
subscriberId: "hello-world-subscriber",
|
||||
}
|
||||
|
||||
await workflowEngineModuleService.subscribe({
|
||||
...subscriptionOptions,
|
||||
subscriber: async (data) => {
|
||||
if (data.eventType === "onFinish") {
|
||||
console.log("Finished execution", data.result)
|
||||
// unsubscribe
|
||||
await workflowEngineModuleService.unsubscribe({
|
||||
...subscriptionOptions,
|
||||
subscriberOrId: subscriptionOptions.subscriberId,
|
||||
})
|
||||
} else if (data.eventType === "onStepFailure") {
|
||||
console.log("Workflow failed", data.step)
|
||||
}
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
<TypeList types={[
|
||||
{
|
||||
"name": "subscriptionOptions",
|
||||
"type": "`object`",
|
||||
"description": "The options for the subscription.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": [
|
||||
{
|
||||
"name": "workflowId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow to subscribe to. This is the first parameter passed to `createWorkflow` when creating the workflow.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "transactionId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow execution's transaction. This is returned when you execute a workflow.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "subscriberId",
|
||||
"type": "`string`",
|
||||
"description": "A unique ID for the subscriber. It's used to unsubscribe from the workflow's events.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "subscriber",
|
||||
"type": "`(data: WorkflowEvent) => void`",
|
||||
"description": "The subscriber function that will be called when the workflow emits an event.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="subscribe"/>
|
||||
|
||||
---
|
||||
|
||||
## unsubscribe
|
||||
|
||||
This method unsubscribes from a workflow's events. You can use this method to stop listening to a [long-running workflow](!docs!/learn/fundamentals/workflows/long-running-workflow)'s events after you've received the result.
|
||||
|
||||
### Example
|
||||
|
||||
```ts
|
||||
await workflowEngineModuleService.unsubscribe({
|
||||
workflowId: "hello-world",
|
||||
transactionId: "transaction-id",
|
||||
subscriberOrId: "hello-world-subscriber",
|
||||
})
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
<TypeList types={[
|
||||
{
|
||||
"name": "workflowId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow to unsubscribe from. This is the first parameter passed to `createWorkflow` when creating the workflow.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "transactionId",
|
||||
"type": "`string`",
|
||||
"description": "The ID of the workflow execution's transaction. This is returned when you execute a workflow.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"name": "subscriberOrId",
|
||||
"type": "`string`",
|
||||
"description": "The subscriber ID or the subscriber function to unsubscribe from the workflow's events.",
|
||||
"optional": false,
|
||||
"defaultValue": "",
|
||||
"expandable": false,
|
||||
"children": []
|
||||
}
|
||||
]} expandUrl="https://docs.medusajs.com/learn/fundamentals/data-models/manage-relationships#retrieve-records-of-relation" sectionTitle="unsubscribe"/>
|
||||
@@ -0,0 +1,40 @@
|
||||
import { Table } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `In-Memory Workflow Engine Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The In-Memory Workflow Engine Module uses a plain JavaScript Map object to store the workflow executions.
|
||||
|
||||
This module is helpful for development or when you’re testing out Medusa, but it’s not recommended to be used in production.
|
||||
|
||||
For production, it’s recommended to use modules like [Redis Workflow Engine Module](../redis/page.mdx).
|
||||
|
||||
---
|
||||
|
||||
## Register the In-Memory Workflow Engine Module
|
||||
|
||||
<Note>
|
||||
|
||||
The In-Memory Workflow Engine Module is registered by default in your application.
|
||||
|
||||
</Note>
|
||||
|
||||
Add the module into the `modules` property of the exported object in `medusa-config.ts`:
|
||||
|
||||
```ts title="medusa-config.ts"
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
// ...
|
||||
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/workflow-engine-inmemory",
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
@@ -0,0 +1,92 @@
|
||||
import { CardList } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Workflow Engine Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
In this document, you'll learn what a Workflow Engine Module is and how to use it in your Medusa application.
|
||||
|
||||
## What is a Workflow Engine Module?
|
||||
|
||||
A Workflow Engine Module handles tracking and recording the transactions and statuses of workflows and their steps. It can use custom mechanism or integrate a third-party service.
|
||||
|
||||
### Default Workflow Engine Module
|
||||
|
||||
Medusa uses the [In-Memory Workflow Engine Module](./in-memory/page.mdx) by default. For production purposes, it's recommended to use the [Redis Workflow Engine Module](./redis/page.mdx) instead.
|
||||
|
||||
---
|
||||
|
||||
## How to Use the Workflow Engine Module?
|
||||
|
||||
You can use the registered Workflow Engine Module as part of the [workflows](!docs!/learn/fundamentals/workflows) you build for your custom features. A workflow is a special function composed of a series of steps that guarantees data consistency and reliable roll-back mechanism.
|
||||
|
||||
In a step of your workflow, you can resolve the Workflow Engine Module's service and use its methods to track and record the transactions and statuses of workflows and their steps.
|
||||
|
||||
For example:
|
||||
|
||||
```ts
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
import {
|
||||
createStep,
|
||||
createWorkflow,
|
||||
StepResponse,
|
||||
WorkflowResponse,
|
||||
} from "@medusajs/framework/workflows-sdk"
|
||||
|
||||
const step1 = createStep(
|
||||
"step-1",
|
||||
async ({}, { container }) => {
|
||||
const workflowEngineService = container.resolve(
|
||||
Modules.WORKFLOW_ENGINE
|
||||
)
|
||||
|
||||
const [workflowExecution] = await workflowEngineService.listWorkflowExecutions({
|
||||
transaction_id: transaction_id,
|
||||
})
|
||||
|
||||
return new StepResponse(workflowExecution)
|
||||
}
|
||||
)
|
||||
|
||||
export const workflow = createWorkflow(
|
||||
"workflow-1",
|
||||
() => {
|
||||
const workflowExecution = step1()
|
||||
|
||||
return new WorkflowResponse(workflowExecution)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
In the example above, you create a workflow that has a step. In the step, you resolve the service of the Workflow Engine Module from the [Medusa container](!docs!/learn/fundamentals/medusa-container).
|
||||
|
||||
Then, you use the `listWorkflowExecutions` method of the Workflow Engine Module to list the workflow executions with the transaction ID `transaction_id`. The workflow execution is then returned as a response from the step and the workflow.
|
||||
|
||||
---
|
||||
|
||||
## List of Workflow Engine Modules
|
||||
|
||||
Medusa provides the following Workflow Engine Modules.
|
||||
|
||||
<CardList
|
||||
items={[
|
||||
{
|
||||
title: "In-Memory",
|
||||
href: "/infrastructure-modules/workflow-engine/in-memory",
|
||||
badge: {
|
||||
variant: "neutral",
|
||||
children: "For Development"
|
||||
}
|
||||
},
|
||||
{
|
||||
title: "Redis",
|
||||
href: "/infrastructure-modules/workflow-engine/redis",
|
||||
badge: {
|
||||
variant: "green",
|
||||
children: "For Production"
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
@@ -0,0 +1,174 @@
|
||||
import { Table, Prerequisites } from "docs-ui"
|
||||
|
||||
export const metadata = {
|
||||
title: `Redis Workflow Engine Module`,
|
||||
}
|
||||
|
||||
# {metadata.title}
|
||||
|
||||
The Redis Workflow Engine Module uses Redis to track workflow executions and handle their subscribers. In production, it's recommended to use this module.
|
||||
|
||||
---
|
||||
|
||||
## Register the Redis Workflow Engine Module
|
||||
|
||||
<Prerequisites items={[
|
||||
{
|
||||
text: "Redis installed and Redis server running",
|
||||
link: "https://redis.io/docs/getting-started/installation/"
|
||||
}
|
||||
]} />
|
||||
|
||||
Add the module into the `modules` property of the exported object in `medusa-config.ts`:
|
||||
|
||||
export const highlights = [
|
||||
["12", "url", "The Redis connection URL."]
|
||||
]
|
||||
|
||||
```ts title="medusa-config.ts" highlights={highlights}
|
||||
import { Modules } from "@medusajs/framework/utils"
|
||||
|
||||
// ...
|
||||
|
||||
module.exports = defineConfig({
|
||||
// ...
|
||||
modules: [
|
||||
{
|
||||
resolve: "@medusajs/medusa/workflow-engine-redis",
|
||||
options: {
|
||||
redis: {
|
||||
url: process.env.WE_REDIS_URL,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Make sure to add the following environment variables:
|
||||
|
||||
```bash
|
||||
WE_REDIS_URL=<YOUR_REDIS_URL>
|
||||
```
|
||||
|
||||
### Redis Workflow Engine Module Options
|
||||
|
||||
<Table>
|
||||
<Table.Header>
|
||||
<Table.Row>
|
||||
<Table.HeaderCell>Option</Table.HeaderCell>
|
||||
<Table.HeaderCell>Description</Table.HeaderCell>
|
||||
<Table.HeaderCell>Required</Table.HeaderCell>
|
||||
<Table.HeaderCell>Default</Table.HeaderCell>
|
||||
</Table.Row>
|
||||
</Table.Header>
|
||||
<Table.Body>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`url`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
A string indicating the Redis connection URL.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
No. If not provided, you must provide the `pubsub` option.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`options`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
An object of Redis options. Refer to the [Redis API Reference](https://redis.github.io/ioredis/index.html#RedisOptions) for details on accepted properties.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
No
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`queueName`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
The name of the queue used to keep track of retries and timeouts.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
No
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
`medusa-workflows`
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
<Table.Row>
|
||||
<Table.Cell>
|
||||
|
||||
`pubsub`
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
A connection object having the following properties:
|
||||
|
||||
- `url`: A required string indicating the Redis connection URL.
|
||||
- `options`: An optional object of Redis options. Refer to the [Redis API Reference](https://redis.github.io/ioredis/index.html#RedisOptions) for details on accepted properties.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
No. If not provided, you must provide the `url` option.
|
||||
|
||||
</Table.Cell>
|
||||
<Table.Cell>
|
||||
|
||||
\-
|
||||
|
||||
</Table.Cell>
|
||||
</Table.Row>
|
||||
</Table.Body>
|
||||
</Table>
|
||||
|
||||
## Test the Module
|
||||
|
||||
To test the module, start the Medusa application:
|
||||
|
||||
```bash npm2yarn
|
||||
npm run dev
|
||||
```
|
||||
|
||||
You'll see the following message in the terminal's logs:
|
||||
|
||||
```bash noCopy noReport
|
||||
Connection to Redis in module 'workflow-engine-redis' established
|
||||
```
|
||||
Reference in New Issue
Block a user