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:
@@ -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) {
|
||||||
|
|||||||
+7
-7
@@ -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,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user