fix: Use a global reference to distributed transaction and scheduler (#8462)

* fix: Add storage cleanup on scheduled jobs

* fix: Use a global reference to distributed transaction and scheduler classes
This commit is contained in:
Stevche Radevski
2024-08-06 14:14:51 +02:00
committed by GitHub
parent c870302400
commit 4155d0354f
16 changed files with 121 additions and 88 deletions
@@ -1,7 +1,7 @@
import { TransactionStepState, TransactionStepStatus } from "@medusajs/utils" import { TransactionStepState, TransactionStepStatus } from "@medusajs/utils"
import { setTimeout } from "timers/promises" import { setTimeout } from "timers/promises"
import { import {
DistributedTransaction, DistributedTransactionType,
TransactionHandlerType, TransactionHandlerType,
TransactionOrchestrator, TransactionOrchestrator,
TransactionPayload, TransactionPayload,
@@ -970,7 +970,7 @@ describe("Transaction Orchestrator", () => {
actionId: string, actionId: string,
functionHandlerType: TransactionHandlerType, functionHandlerType: TransactionHandlerType,
payload: TransactionPayload, payload: TransactionPayload,
transaction?: DistributedTransaction transaction?: DistributedTransactionType
) { ) {
transactionInHandler = transaction transactionInHandler = transaction
} }
@@ -1,5 +1,5 @@
import { import {
DistributedTransaction, DistributedTransactionType,
TransactionCheckpoint, TransactionCheckpoint,
} from "../distributed-transaction" } from "../distributed-transaction"
import { TransactionStep } from "../transaction-step" import { TransactionStep } from "../transaction-step"
@@ -29,29 +29,31 @@ export interface IDistributedTransactionStorage {
options?: TransactionOptions options?: TransactionOptions
): Promise<void> ): Promise<void>
scheduleRetry( scheduleRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
): Promise<void> ): Promise<void>
clearRetry( clearRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> ): Promise<void>
scheduleTransactionTimeout( scheduleTransactionTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
timestamp: number, timestamp: number,
interval: number interval: number
): Promise<void> ): Promise<void>
scheduleStepTimeout( scheduleStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
): Promise<void> ): Promise<void>
clearTransactionTimeout(transaction: DistributedTransaction): Promise<void> clearTransactionTimeout(
transaction: DistributedTransactionType
): Promise<void>
clearStepTimeout( clearStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> ): Promise<void>
} }
@@ -103,7 +105,7 @@ export abstract class DistributedTransactionStorage
} }
async scheduleRetry( async scheduleRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
@@ -112,14 +114,14 @@ export abstract class DistributedTransactionStorage
} }
async clearRetry( async clearRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> { ): Promise<void> {
throw new Error("Method 'clearRetry' not implemented.") throw new Error("Method 'clearRetry' not implemented.")
} }
async scheduleTransactionTimeout( async scheduleTransactionTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
timestamp: number, timestamp: number,
interval: number interval: number
): Promise<void> { ): Promise<void> {
@@ -127,13 +129,13 @@ export abstract class DistributedTransactionStorage
} }
async clearTransactionTimeout( async clearTransactionTimeout(
transaction: DistributedTransaction transaction: DistributedTransactionType
): Promise<void> { ): Promise<void> {
throw new Error("Method 'clearTransactionTimeout' not implemented.") throw new Error("Method 'clearTransactionTimeout' not implemented.")
} }
async scheduleStepTimeout( async scheduleStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
@@ -142,7 +144,7 @@ export abstract class DistributedTransactionStorage
} }
async clearStepTimeout( async clearStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> { ): Promise<void> {
throw new Error("Method 'clearStepTimeout' not implemented.") throw new Error("Method 'clearStepTimeout' not implemented.")
@@ -74,7 +74,7 @@ export class TransactionPayload {
* DistributedTransaction represents a distributed transaction, which is a transaction that is composed of multiple steps that are executed in a specific order. * DistributedTransaction represents a distributed transaction, which is a transaction that is composed of multiple steps that are executed in a specific order.
*/ */
export class DistributedTransaction extends EventEmitter { class DistributedTransaction extends EventEmitter {
public modelId: string public modelId: string
public transactionId: string public transactionId: string
@@ -302,3 +302,12 @@ export class DistributedTransaction extends EventEmitter {
DistributedTransaction.setStorage( DistributedTransaction.setStorage(
new BaseInMemoryDistributedTransactionStorage() new BaseInMemoryDistributedTransactionStorage()
) )
global.DistributedTransaction ??= DistributedTransaction
const GlobalDistributedTransaction =
global.DistributedTransaction as typeof DistributedTransaction
export {
GlobalDistributedTransaction as DistributedTransaction,
DistributedTransaction as DistributedTransactionType,
}
@@ -1,5 +1,6 @@
import { import {
DistributedTransaction, DistributedTransaction,
DistributedTransactionType,
TransactionCheckpoint, TransactionCheckpoint,
TransactionPayload, TransactionPayload,
} from "./distributed-transaction" } from "./distributed-transaction"
@@ -173,7 +174,7 @@ export class TransactionOrchestrator extends EventEmitter {
transaction, transaction,
step, step,
}: { }: {
transaction?: DistributedTransaction transaction?: DistributedTransactionType
step?: TransactionStep step?: TransactionStep
}, },
dateNow: number dateNow: number
@@ -195,7 +196,7 @@ export class TransactionOrchestrator extends EventEmitter {
} }
private async checkTransactionTimeout( private async checkTransactionTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
currentSteps: TransactionStep[] currentSteps: TransactionStep[]
) { ) {
const flow = transaction.getFlow() const flow = transaction.getFlow()
@@ -224,7 +225,7 @@ export class TransactionOrchestrator extends EventEmitter {
} }
private async checkStepTimeout( private async checkStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
) { ) {
let hasTimedOut = false let hasTimedOut = false
@@ -249,7 +250,9 @@ export class TransactionOrchestrator extends EventEmitter {
return hasTimedOut return hasTimedOut
} }
private async checkAllSteps(transaction: DistributedTransaction): Promise<{ private async checkAllSteps(
transaction: DistributedTransactionType
): Promise<{
current: TransactionStep[] current: TransactionStep[]
next: TransactionStep[] next: TransactionStep[]
total: number total: number
@@ -413,7 +416,7 @@ export class TransactionOrchestrator extends EventEmitter {
} }
private static async setStepSuccess( private static async setStepSuccess(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
response: unknown response: unknown
): Promise<void> { ): Promise<void> {
@@ -464,7 +467,7 @@ export class TransactionOrchestrator extends EventEmitter {
} }
private static async skipStep( private static async skipStep(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> { ): Promise<void> {
const hasStepTimedOut = const hasStepTimedOut =
@@ -497,7 +500,7 @@ export class TransactionOrchestrator extends EventEmitter {
} }
private static async setStepTimeout( private static async setStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
error: TransactionStepTimeoutError | TransactionTimeoutError error: TransactionStepTimeoutError | TransactionTimeoutError
): Promise<void> { ): Promise<void> {
@@ -532,7 +535,7 @@ export class TransactionOrchestrator extends EventEmitter {
} }
private static async setStepFailure( private static async setStepFailure(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
error: Error | any, error: Error | any,
maxRetries: number = TransactionOrchestrator.DEFAULT_RETRIES, maxRetries: number = TransactionOrchestrator.DEFAULT_RETRIES,
@@ -611,7 +614,7 @@ export class TransactionOrchestrator extends EventEmitter {
} }
private async executeNext( private async executeNext(
transaction: DistributedTransaction transaction: DistributedTransactionType
): Promise<void> { ): Promise<void> {
let continueExecution = true let continueExecution = true
@@ -854,7 +857,7 @@ export class TransactionOrchestrator extends EventEmitter {
* Start a new transaction or resume a transaction that has been previously started * Start a new transaction or resume a transaction that has been previously started
* @param transaction - The transaction to resume * @param transaction - The transaction to resume
*/ */
public async resume(transaction: DistributedTransaction): Promise<void> { public async resume(transaction: DistributedTransactionType): Promise<void> {
if (transaction.modelId !== this.id) { if (transaction.modelId !== this.id) {
throw new MedusaError( throw new MedusaError(
MedusaError.Types.NOT_ALLOWED, MedusaError.Types.NOT_ALLOWED,
@@ -895,7 +898,7 @@ export class TransactionOrchestrator extends EventEmitter {
* @param transaction - The transaction to be reverted * @param transaction - The transaction to be reverted
*/ */
public async cancelTransaction( public async cancelTransaction(
transaction: DistributedTransaction transaction: DistributedTransactionType
): Promise<void> { ): Promise<void> {
if (transaction.modelId !== this.id) { if (transaction.modelId !== this.id) {
throw new MedusaError( throw new MedusaError(
@@ -1106,7 +1109,7 @@ export class TransactionOrchestrator extends EventEmitter {
handler: TransactionStepHandler, handler: TransactionStepHandler,
payload?: unknown, payload?: unknown,
flowMetadata?: TransactionFlow["metadata"] flowMetadata?: TransactionFlow["metadata"]
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
const existingTransaction = const existingTransaction =
await TransactionOrchestrator.loadTransactionById(this.id, transactionId) await TransactionOrchestrator.loadTransactionById(this.id, transactionId)
@@ -1147,7 +1150,7 @@ export class TransactionOrchestrator extends EventEmitter {
public async retrieveExistingTransaction( public async retrieveExistingTransaction(
transactionId: string, transactionId: string,
handler: TransactionStepHandler handler: TransactionStepHandler
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
const existingTransaction = const existingTransaction =
await TransactionOrchestrator.loadTransactionById(this.id, transactionId) await TransactionOrchestrator.loadTransactionById(this.id, transactionId)
@@ -1184,8 +1187,8 @@ export class TransactionOrchestrator extends EventEmitter {
private static async getTransactionAndStepFromIdempotencyKey( private static async getTransactionAndStepFromIdempotencyKey(
responseIdempotencyKey: string, responseIdempotencyKey: string,
handler?: TransactionStepHandler, handler?: TransactionStepHandler,
transaction?: DistributedTransaction transaction?: DistributedTransactionType
): Promise<[DistributedTransaction, TransactionStep]> { ): Promise<[DistributedTransactionType, TransactionStep]> {
const [modelId, transactionId, action, actionType] = const [modelId, transactionId, action, actionType] =
responseIdempotencyKey.split(TransactionOrchestrator.SEPARATOR) responseIdempotencyKey.split(TransactionOrchestrator.SEPARATOR)
@@ -1243,8 +1246,8 @@ export class TransactionOrchestrator extends EventEmitter {
public async skipStep( public async skipStep(
responseIdempotencyKey: string, responseIdempotencyKey: string,
handler?: TransactionStepHandler, handler?: TransactionStepHandler,
transaction?: DistributedTransaction transaction?: DistributedTransactionType
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
const [curTransaction, step] = const [curTransaction, step] =
await TransactionOrchestrator.getTransactionAndStepFromIdempotencyKey( await TransactionOrchestrator.getTransactionAndStepFromIdempotencyKey(
responseIdempotencyKey, responseIdempotencyKey,
@@ -1279,9 +1282,9 @@ export class TransactionOrchestrator extends EventEmitter {
public async registerStepSuccess( public async registerStepSuccess(
responseIdempotencyKey: string, responseIdempotencyKey: string,
handler?: TransactionStepHandler, handler?: TransactionStepHandler,
transaction?: DistributedTransaction, transaction?: DistributedTransactionType,
response?: unknown response?: unknown
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
const [curTransaction, step] = const [curTransaction, step] =
await TransactionOrchestrator.getTransactionAndStepFromIdempotencyKey( await TransactionOrchestrator.getTransactionAndStepFromIdempotencyKey(
responseIdempotencyKey, responseIdempotencyKey,
@@ -1323,8 +1326,8 @@ export class TransactionOrchestrator extends EventEmitter {
responseIdempotencyKey: string, responseIdempotencyKey: string,
error?: Error | any, error?: Error | any,
handler?: TransactionStepHandler, handler?: TransactionStepHandler,
transaction?: DistributedTransaction transaction?: DistributedTransactionType
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
const [curTransaction, step] = const [curTransaction, step] =
await TransactionOrchestrator.getTransactionAndStepFromIdempotencyKey( await TransactionOrchestrator.getTransactionAndStepFromIdempotencyKey(
responseIdempotencyKey, responseIdempotencyKey,
@@ -1,6 +1,6 @@
import { MedusaError, TransactionStepState } from "@medusajs/utils" import { MedusaError, TransactionStepState } from "@medusajs/utils"
import { import {
DistributedTransaction, DistributedTransactionType,
TransactionPayload, TransactionPayload,
} from "./distributed-transaction" } from "./distributed-transaction"
import { TransactionOrchestrator } from "./transaction-orchestrator" import { TransactionOrchestrator } from "./transaction-orchestrator"
@@ -15,7 +15,7 @@ export type TransactionStepHandler = (
actionId: string, actionId: string,
handlerType: TransactionHandlerType, handlerType: TransactionHandlerType,
payload: TransactionPayload, payload: TransactionPayload,
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
orchestrator: TransactionOrchestrator orchestrator: TransactionOrchestrator
) => Promise<unknown> ) => Promise<unknown>
@@ -1,4 +1,4 @@
import { DistributedTransaction } from "./distributed-transaction" import { DistributedTransactionType } from "./distributed-transaction"
import { TransactionStep } from "./transaction-step" import { TransactionStep } from "./transaction-step"
export { export {
TransactionHandlerType, TransactionHandlerType,
@@ -172,50 +172,52 @@ export enum DistributedTransactionEvent {
} }
export type DistributedTransactionEvents = { export type DistributedTransactionEvents = {
onBegin?: (args: { transaction: DistributedTransaction }) => void onBegin?: (args: { transaction: DistributedTransactionType }) => void
onResume?: (args: { transaction: DistributedTransaction }) => void onResume?: (args: { transaction: DistributedTransactionType }) => void
onFinish?: (args: { onFinish?: (args: {
transaction: DistributedTransaction transaction: DistributedTransactionType
result?: unknown result?: unknown
errors?: unknown[] errors?: unknown[]
}) => void }) => void
onTimeout?: (args: { transaction: DistributedTransaction }) => void onTimeout?: (args: { transaction: DistributedTransactionType }) => void
onStepBegin?: (args: { onStepBegin?: (args: {
step: TransactionStep step: TransactionStep
transaction: DistributedTransaction transaction: DistributedTransactionType
}) => void }) => void
onStepSuccess?: (args: { onStepSuccess?: (args: {
step: TransactionStep step: TransactionStep
transaction: DistributedTransaction transaction: DistributedTransactionType
}) => void }) => void
onStepFailure?: (args: { onStepFailure?: (args: {
step: TransactionStep step: TransactionStep
transaction: DistributedTransaction transaction: DistributedTransactionType
}) => void }) => void
onStepAwaiting?: (args: { onStepAwaiting?: (args: {
step: TransactionStep step: TransactionStep
transaction: DistributedTransaction transaction: DistributedTransactionType
}) => void }) => void
onCompensateBegin?: (args: { transaction: DistributedTransaction }) => void onCompensateBegin?: (args: {
transaction: DistributedTransactionType
}) => void
onCompensateStepSuccess?: (args: { onCompensateStepSuccess?: (args: {
step: TransactionStep step: TransactionStep
transaction: DistributedTransaction transaction: DistributedTransactionType
}) => void }) => void
onCompensateStepFailure?: (args: { onCompensateStepFailure?: (args: {
step: TransactionStep step: TransactionStep
transaction: DistributedTransaction transaction: DistributedTransactionType
}) => void }) => void
onStepSkipped?: (args: { onStepSkipped?: (args: {
step: TransactionStep step: TransactionStep
transaction: DistributedTransaction transaction: DistributedTransactionType
}) => void }) => void
} }
@@ -3,7 +3,7 @@ import { createMedusaContainer } from "@medusajs/utils"
import { asValue } from "awilix" import { asValue } from "awilix"
import { import {
DistributedTransaction, DistributedTransactionType,
DistributedTransactionEvents, DistributedTransactionEvents,
} from "../transaction" } from "../transaction"
import { WorkflowDefinition, WorkflowManager } from "./workflow-manager" import { WorkflowDefinition, WorkflowManager } from "./workflow-manager"
@@ -83,7 +83,7 @@ export class GlobalWorkflow extends WorkflowManager {
workflowId: string, workflowId: string,
idempotencyKey: string, idempotencyKey: string,
response?: unknown response?: unknown
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
if (!WorkflowManager.workflows.has(workflowId)) { if (!WorkflowManager.workflows.has(workflowId)) {
throw new Error(`Workflow with id "${workflowId}" not found.`) throw new Error(`Workflow with id "${workflowId}" not found.`)
} }
@@ -116,7 +116,7 @@ export class GlobalWorkflow extends WorkflowManager {
workflowId: string, workflowId: string,
idempotencyKey: string, idempotencyKey: string,
error?: Error | any error?: Error | any
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
if (!WorkflowManager.workflows.has(workflowId)) { if (!WorkflowManager.workflows.has(workflowId)) {
throw new Error(`Workflow with id "${workflowId}" not found.`) throw new Error(`Workflow with id "${workflowId}" not found.`)
} }
@@ -10,7 +10,7 @@ import {
} from "@medusajs/utils" } from "@medusajs/utils"
import { asValue } from "awilix" import { asValue } from "awilix"
import { import {
DistributedTransaction, DistributedTransactionType,
DistributedTransactionEvent, DistributedTransactionEvent,
DistributedTransactionEvents, DistributedTransactionEvents,
TransactionFlow, TransactionFlow,
@@ -167,7 +167,7 @@ export class LocalWorkflow {
idempotencyKey, idempotencyKey,
}: { }: {
orchestrator: TransactionOrchestrator orchestrator: TransactionOrchestrator
transaction?: DistributedTransaction transaction?: DistributedTransactionType
subscribe?: DistributedTransactionEvents subscribe?: DistributedTransactionEvents
idempotencyKey?: string idempotencyKey?: string
}) { }) {
@@ -382,7 +382,7 @@ export class LocalWorkflow {
} }
async cancel( async cancel(
transactionOrTransactionId: string | DistributedTransaction, transactionOrTransactionId: string | DistributedTransactionType,
context?: Context, context?: Context,
subscribe?: DistributedTransactionEvents subscribe?: DistributedTransactionEvents
) { ) {
@@ -411,7 +411,7 @@ export class LocalWorkflow {
response?: unknown, response?: unknown,
context?: Context, context?: Context,
subscribe?: DistributedTransactionEvents subscribe?: DistributedTransactionEvents
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
this.medusaContext = context this.medusaContext = context
const { handler, orchestrator } = this.workflow const { handler, orchestrator } = this.workflow
@@ -438,7 +438,7 @@ export class LocalWorkflow {
error?: Error | any, error?: Error | any,
context?: Context, context?: Context,
subscribe?: DistributedTransactionEvents subscribe?: DistributedTransactionEvents
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
this.medusaContext = context this.medusaContext = context
const { handler, orchestrator } = this.workflow const { handler, orchestrator } = this.workflow
@@ -2,7 +2,7 @@ import { MedusaError } from "@medusajs/utils"
import { IDistributedSchedulerStorage, SchedulerOptions } from "../transaction" import { IDistributedSchedulerStorage, SchedulerOptions } from "../transaction"
import { WorkflowDefinition } from "./workflow-manager" import { WorkflowDefinition } from "./workflow-manager"
export class WorkflowScheduler { class WorkflowScheduler {
private static storage: IDistributedSchedulerStorage private static storage: IDistributedSchedulerStorage
public static setStorage(storage: IDistributedSchedulerStorage) { public static setStorage(storage: IDistributedSchedulerStorage) {
this.storage = storage this.storage = storage
@@ -40,3 +40,9 @@ export class WorkflowScheduler {
await WorkflowScheduler.storage.removeAll() await WorkflowScheduler.storage.removeAll()
} }
} }
global.WorkflowScheduler ??= WorkflowScheduler
const GlobalWorkflowScheduler =
global.WorkflowScheduler as typeof WorkflowScheduler
export { GlobalWorkflowScheduler as WorkflowScheduler }
@@ -1,6 +1,6 @@
import { Context, MedusaContainer } from "@medusajs/types" import { Context, MedusaContainer } from "@medusajs/types"
import { import {
DistributedTransaction, DistributedTransactionType,
OrchestratorBuilder, OrchestratorBuilder,
TransactionHandlerType, TransactionHandlerType,
TransactionMetadata, TransactionMetadata,
@@ -40,7 +40,7 @@ export type WorkflowStepHandlerArguments = {
invoke: { [actions: string]: unknown } invoke: { [actions: string]: unknown }
compensate: { [actions: string]: unknown } compensate: { [actions: string]: unknown }
metadata: TransactionMetadata metadata: TransactionMetadata
transaction: DistributedTransaction transaction: DistributedTransactionType
step: TransactionStep step: TransactionStep
orchestrator: TransactionOrchestrator orchestrator: TransactionOrchestrator
context?: Context context?: Context
@@ -194,7 +194,7 @@ class WorkflowManager {
actionId: string, actionId: string,
handlerType: TransactionHandlerType, handlerType: TransactionHandlerType,
payload: any, payload: any,
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
orchestrator: TransactionOrchestrator orchestrator: TransactionOrchestrator
) => { ) => {
@@ -217,7 +217,7 @@ class WorkflowManager {
invoke, invoke,
compensate, compensate,
metadata, metadata,
transaction: transaction as DistributedTransaction, transaction: transaction as DistributedTransactionType,
step, step,
orchestrator, orchestrator,
context, context,
@@ -1,6 +1,6 @@
import { Context, LoadedModule, MedusaContainer } from "@medusajs/types" import { Context, LoadedModule, MedusaContainer } from "@medusajs/types"
import { import {
DistributedTransaction, DistributedTransactionType,
DistributedTransactionEvents, DistributedTransactionEvents,
LocalWorkflow, LocalWorkflow,
TransactionStepError, TransactionStepError,
@@ -36,7 +36,7 @@ export type FlowRegisterStepFailureOptions<TData = unknown> = {
} }
export type FlowCancelOptions = { export type FlowCancelOptions = {
transaction?: DistributedTransaction transaction?: DistributedTransactionType
transactionId?: string transactionId?: string
context?: Context context?: Context
throwOnError?: boolean throwOnError?: boolean
@@ -55,7 +55,7 @@ export type WorkflowResult<TResult = unknown> = {
/** /**
* The transaction details of the workflow's execution. * The transaction details of the workflow's execution.
*/ */
transaction: DistributedTransaction transaction: DistributedTransactionType
/** /**
* The result returned by the workflow. * The result returned by the workflow.
*/ */
@@ -1,6 +1,6 @@
import { MedusaModule } from "@medusajs/modules-sdk" import { MedusaModule } from "@medusajs/modules-sdk"
import { import {
DistributedTransaction, DistributedTransactionType,
DistributedTransactionEvents, DistributedTransactionEvents,
LocalWorkflow, LocalWorkflow,
TransactionHandlerType, TransactionHandlerType,
@@ -66,7 +66,7 @@ function createContextualWorkflowRunner<
isCancel = false, isCancel = false,
container: executionContainer, container: executionContainer,
}, },
transactionOrIdOrIdempotencyKey: DistributedTransaction | string, transactionOrIdOrIdempotencyKey: DistributedTransactionType | string,
input: unknown, input: unknown,
context: Context, context: Context,
events: DistributedTransactionEvents | undefined = {} events: DistributedTransactionEvents | undefined = {}
@@ -483,7 +483,7 @@ function attachOnFinishReleaseEvents(
const onFinish = events.onFinish const onFinish = events.onFinish
const wrappedOnFinish = async (args: { const wrappedOnFinish = async (args: {
transaction: DistributedTransaction transaction: DistributedTransactionType
result?: unknown result?: unknown
errors?: unknown[] errors?: unknown[]
}) => { }) => {
@@ -1,5 +1,6 @@
import { import {
DistributedTransaction, DistributedTransaction,
DistributedTransactionType,
DistributedTransactionEvents, DistributedTransactionEvents,
TransactionHandlerType, TransactionHandlerType,
TransactionStep, TransactionStep,
@@ -178,7 +179,7 @@ export class WorkflowOrchestratorService {
transactionId: string, transactionId: string,
options?: WorkflowOrchestratorRunOptions<undefined>, options?: WorkflowOrchestratorRunOptions<undefined>,
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
let { context, container } = options ?? {} let { context, container } = options ?? {}
if (!workflowId) { if (!workflowId) {
@@ -1,5 +1,5 @@
import { import {
DistributedTransaction, DistributedTransactionType,
IDistributedSchedulerStorage, IDistributedSchedulerStorage,
IDistributedTransactionStorage, IDistributedTransactionStorage,
SchedulerOptions, SchedulerOptions,
@@ -155,7 +155,7 @@ export class InMemoryDistributedTransactionStorage
} }
async scheduleRetry( async scheduleRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
@@ -174,7 +174,7 @@ export class InMemoryDistributedTransactionStorage
} }
async clearRetry( async clearRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> { ): Promise<void> {
const { modelId: workflowId, transactionId } = transaction const { modelId: workflowId, transactionId } = transaction
@@ -188,7 +188,7 @@ export class InMemoryDistributedTransactionStorage
} }
async scheduleTransactionTimeout( async scheduleTransactionTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
timestamp: number, timestamp: number,
interval: number interval: number
): Promise<void> { ): Promise<void> {
@@ -206,7 +206,7 @@ export class InMemoryDistributedTransactionStorage
} }
async clearTransactionTimeout( async clearTransactionTimeout(
transaction: DistributedTransaction transaction: DistributedTransactionType
): Promise<void> { ): Promise<void> {
const { modelId: workflowId, transactionId } = transaction const { modelId: workflowId, transactionId } = transaction
@@ -219,7 +219,7 @@ export class InMemoryDistributedTransactionStorage
} }
async scheduleStepTimeout( async scheduleStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
@@ -238,7 +238,7 @@ export class InMemoryDistributedTransactionStorage
} }
async clearStepTimeout( async clearStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> { ): Promise<void> {
const { modelId: workflowId, transactionId } = transaction const { modelId: workflowId, transactionId } = transaction
@@ -1,5 +1,6 @@
import { import {
DistributedTransaction, DistributedTransaction,
DistributedTransactionType,
DistributedTransactionEvents, DistributedTransactionEvents,
TransactionHandlerType, TransactionHandlerType,
TransactionStep, TransactionStep,
@@ -221,7 +222,7 @@ export class WorkflowOrchestratorService {
transactionId: string, transactionId: string,
options?: WorkflowOrchestratorRunOptions<undefined>, options?: WorkflowOrchestratorRunOptions<undefined>,
@MedusaContext() sharedContext: Context = {} @MedusaContext() sharedContext: Context = {}
): Promise<DistributedTransaction> { ): Promise<DistributedTransactionType> {
let { context, container } = options ?? {} let { context, container } = options ?? {}
if (!workflowId) { if (!workflowId) {
@@ -1,5 +1,6 @@
import { import {
DistributedTransaction, DistributedTransaction,
DistributedTransactionType,
IDistributedSchedulerStorage, IDistributedSchedulerStorage,
IDistributedTransactionStorage, IDistributedTransactionStorage,
SchedulerOptions, SchedulerOptions,
@@ -256,7 +257,7 @@ export class RedisDistributedTransactionStorage
} }
async scheduleRetry( async scheduleRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
@@ -277,14 +278,14 @@ export class RedisDistributedTransactionStorage
} }
async clearRetry( async clearRetry(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> { ): Promise<void> {
await this.removeJob(JobType.RETRY, transaction, step) await this.removeJob(JobType.RETRY, transaction, step)
} }
async scheduleTransactionTimeout( async scheduleTransactionTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
timestamp: number, timestamp: number,
interval: number interval: number
): Promise<void> { ): Promise<void> {
@@ -303,13 +304,13 @@ export class RedisDistributedTransactionStorage
} }
async clearTransactionTimeout( async clearTransactionTimeout(
transaction: DistributedTransaction transaction: DistributedTransactionType
): Promise<void> { ): Promise<void> {
await this.removeJob(JobType.TRANSACTION_TIMEOUT, transaction) await this.removeJob(JobType.TRANSACTION_TIMEOUT, transaction)
} }
async scheduleStepTimeout( async scheduleStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep, step: TransactionStep,
timestamp: number, timestamp: number,
interval: number interval: number
@@ -330,7 +331,7 @@ export class RedisDistributedTransactionStorage
} }
async clearStepTimeout( async clearStepTimeout(
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step: TransactionStep step: TransactionStep
): Promise<void> { ): Promise<void> {
await this.removeJob(JobType.STEP_TIMEOUT, transaction, step) await this.removeJob(JobType.STEP_TIMEOUT, transaction, step)
@@ -338,7 +339,7 @@ export class RedisDistributedTransactionStorage
private getJobId( private getJobId(
type: JobType, type: JobType,
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step?: TransactionStep step?: TransactionStep
) { ) {
const key = [type, transaction.modelId, transaction.transactionId] const key = [type, transaction.modelId, transaction.transactionId]
@@ -355,7 +356,7 @@ export class RedisDistributedTransactionStorage
private async removeJob( private async removeJob(
type: JobType, type: JobType,
transaction: DistributedTransaction, transaction: DistributedTransactionType,
step?: TransactionStep step?: TransactionStep
) { ) {
const jobId = this.getJobId(type, transaction, step) const jobId = this.getJobId(type, transaction, step)
@@ -387,6 +388,14 @@ export class RedisDistributedTransactionStorage
limit: schedulerOptions.numberOfExecutions, limit: schedulerOptions.numberOfExecutions,
key: `${JobType.SCHEDULE}_${jobId}`, key: `${JobType.SCHEDULE}_${jobId}`,
}, },
removeOnComplete: {
age: 86400,
count: 1000,
},
removeOnFail: {
age: 604800,
count: 5000,
},
} }
) )
} }