feat: Ensure async workflow executions have access to shared container (#8157)
* feat: Ensure async workflow executions have access to shared container * fix: Register workflow worker on application start
This commit is contained in:
@@ -56,6 +56,8 @@ export async function initModules({
|
|||||||
injectedDependencies,
|
injectedDependencies,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await medusaApp.onApplicationStart()
|
||||||
|
|
||||||
async function shutdown() {
|
async function shutdown() {
|
||||||
if (shouldDestroyConnectionAutomatically) {
|
if (shouldDestroyConnectionAutomatically) {
|
||||||
await medusaApp.onApplicationPrepareShutdown()
|
await medusaApp.onApplicationPrepareShutdown()
|
||||||
|
|||||||
@@ -145,6 +145,7 @@ export const ModulesDefinition: {
|
|||||||
isRequired: false,
|
isRequired: false,
|
||||||
isQueryable: true,
|
isQueryable: true,
|
||||||
dependencies: ["logger"],
|
dependencies: ["logger"],
|
||||||
|
__passSharedContainer: true,
|
||||||
defaultModuleDeclaration: {
|
defaultModuleDeclaration: {
|
||||||
scope: MODULE_SCOPE.INTERNAL,
|
scope: MODULE_SCOPE.INTERNAL,
|
||||||
resources: MODULE_RESOURCE_TYPE.SHARED,
|
resources: MODULE_RESOURCE_TYPE.SHARED,
|
||||||
|
|||||||
@@ -139,6 +139,15 @@ export async function loadInternalModule(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resolution.definition.__passSharedContainer) {
|
||||||
|
localContainer.register(
|
||||||
|
"sharedContainer",
|
||||||
|
asFunction(() => {
|
||||||
|
return container
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const loaders = moduleResources.loaders ?? loadedModule?.loaders ?? []
|
const loaders = moduleResources.loaders ?? loadedModule?.loaders ?? []
|
||||||
const error = await runLoaders(loaders, {
|
const error = await runLoaders(loaders, {
|
||||||
container,
|
container,
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ export type MedusaAppOutput = {
|
|||||||
generateMigrations: GenerateMigrations
|
generateMigrations: GenerateMigrations
|
||||||
onApplicationShutdown: () => Promise<void>
|
onApplicationShutdown: () => Promise<void>
|
||||||
onApplicationPrepareShutdown: () => Promise<void>
|
onApplicationPrepareShutdown: () => Promise<void>
|
||||||
|
onApplicationStart: () => Promise<void>
|
||||||
sharedContainer?: MedusaContainer
|
sharedContainer?: MedusaContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -284,6 +285,10 @@ async function MedusaApp_({
|
|||||||
await promiseAll([MedusaModule.onApplicationPrepareShutdown()])
|
await promiseAll([MedusaModule.onApplicationPrepareShutdown()])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onApplicationStart = async () => {
|
||||||
|
await MedusaModule.onApplicationStart()
|
||||||
|
}
|
||||||
|
|
||||||
const modules: MedusaModuleConfig =
|
const modules: MedusaModuleConfig =
|
||||||
modulesConfig ??
|
modulesConfig ??
|
||||||
(
|
(
|
||||||
@@ -349,6 +354,7 @@ async function MedusaApp_({
|
|||||||
return {
|
return {
|
||||||
onApplicationShutdown,
|
onApplicationShutdown,
|
||||||
onApplicationPrepareShutdown,
|
onApplicationPrepareShutdown,
|
||||||
|
onApplicationStart,
|
||||||
modules: allModules,
|
modules: allModules,
|
||||||
link: undefined,
|
link: undefined,
|
||||||
query: async () => {
|
query: async () => {
|
||||||
@@ -536,6 +542,7 @@ async function MedusaApp_({
|
|||||||
return {
|
return {
|
||||||
onApplicationShutdown,
|
onApplicationShutdown,
|
||||||
onApplicationPrepareShutdown,
|
onApplicationPrepareShutdown,
|
||||||
|
onApplicationStart,
|
||||||
modules: allModules,
|
modules: allModules,
|
||||||
link: remoteLink,
|
link: remoteLink,
|
||||||
query,
|
query,
|
||||||
@@ -551,11 +558,7 @@ async function MedusaApp_({
|
|||||||
export async function MedusaApp(
|
export async function MedusaApp(
|
||||||
options: MedusaAppOptions = {}
|
options: MedusaAppOptions = {}
|
||||||
): Promise<MedusaAppOutput> {
|
): Promise<MedusaAppOutput> {
|
||||||
try {
|
return await MedusaApp_(options)
|
||||||
return await MedusaApp_(options)
|
|
||||||
} finally {
|
|
||||||
MedusaModule.onApplicationStart(options.onApplicationStartCb)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function MedusaAppMigrateUp(
|
export async function MedusaAppMigrateUp(
|
||||||
|
|||||||
@@ -87,6 +87,8 @@ export type ModuleDefinition = {
|
|||||||
isRequired?: boolean
|
isRequired?: boolean
|
||||||
isQueryable?: boolean // If the module is queryable via Remote Joiner
|
isQueryable?: boolean // If the module is queryable via Remote Joiner
|
||||||
dependencies?: string[]
|
dependencies?: string[]
|
||||||
|
/** @internal only used in exceptional cases - relying on the shared contrainer breaks encapsulation */
|
||||||
|
__passSharedContainer?: boolean
|
||||||
defaultModuleDeclaration:
|
defaultModuleDeclaration:
|
||||||
| InternalModuleDeclaration
|
| InternalModuleDeclaration
|
||||||
| ExternalModuleDeclaration
|
| ExternalModuleDeclaration
|
||||||
|
|||||||
@@ -153,14 +153,17 @@ export default async ({
|
|||||||
|
|
||||||
const plugins = getResolvedPlugins(rootDirectory, configModule, true) || []
|
const plugins = getResolvedPlugins(rootDirectory, configModule, true) || []
|
||||||
const pluginLinks = await resolvePluginsLinks(plugins, container)
|
const pluginLinks = await resolvePluginsLinks(plugins, container)
|
||||||
|
|
||||||
|
const {
|
||||||
|
onApplicationStart,
|
||||||
|
onApplicationShutdown,
|
||||||
|
onApplicationPrepareShutdown,
|
||||||
|
} = await loadMedusaApp({
|
||||||
|
container,
|
||||||
|
linkModules: pluginLinks,
|
||||||
|
})
|
||||||
|
|
||||||
await registerWorkflows(plugins)
|
await registerWorkflows(plugins)
|
||||||
|
|
||||||
const { onApplicationShutdown, onApplicationPrepareShutdown } =
|
|
||||||
await loadMedusaApp({
|
|
||||||
container,
|
|
||||||
linkModules: pluginLinks,
|
|
||||||
})
|
|
||||||
|
|
||||||
const entrypointsShutdown = await loadEntrypoints(
|
const entrypointsShutdown = await loadEntrypoints(
|
||||||
plugins,
|
plugins,
|
||||||
container,
|
container,
|
||||||
@@ -168,6 +171,7 @@ export default async ({
|
|||||||
rootDirectory
|
rootDirectory
|
||||||
)
|
)
|
||||||
await createDefaultsWorkflow(container).run()
|
await createDefaultsWorkflow(container).run()
|
||||||
|
await onApplicationStart()
|
||||||
|
|
||||||
const shutdown = async () => {
|
const shutdown = async () => {
|
||||||
const pgConnection = container.resolve(
|
const pgConnection = container.resolve(
|
||||||
|
|||||||
+4
-2
@@ -6,8 +6,10 @@ import {
|
|||||||
} from "@medusajs/workflows-sdk"
|
} from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
export const createScheduled = (name: string, schedule?: SchedulerOptions) => {
|
export const createScheduled = (name: string, schedule?: SchedulerOptions) => {
|
||||||
const workflowScheduledStepInvoke = jest.fn((input, context) => {
|
const workflowScheduledStepInvoke = jest.fn((input, { container }) => {
|
||||||
return new StepResponse({})
|
return new StepResponse({
|
||||||
|
testValue: container.resolve("test-value"),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const step = createStep("step_1", workflowScheduledStepInvoke)
|
const step = createStep("step_1", workflowScheduledStepInvoke)
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
} from "../__fixtures__/workflow_event_group_id"
|
} from "../__fixtures__/workflow_event_group_id"
|
||||||
import { createScheduled } from "../__fixtures__/workflow_scheduled"
|
import { createScheduled } from "../__fixtures__/workflow_scheduled"
|
||||||
import { WorkflowsModuleService } from "@services"
|
import { WorkflowsModuleService } from "@services"
|
||||||
|
import { asFunction } from "awilix"
|
||||||
|
|
||||||
jest.setTimeout(100000)
|
jest.setTimeout(100000)
|
||||||
|
|
||||||
@@ -367,6 +368,25 @@ moduleIntegrationTestRunner<IWorkflowEngineService>({
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("the scheduled workflow should have access to the shared container", async () => {
|
||||||
|
const sharedContainer =
|
||||||
|
workflowOrcModule["workflowOrchestratorService_"]["container_"]
|
||||||
|
|
||||||
|
sharedContainer.register(
|
||||||
|
"test-value",
|
||||||
|
asFunction(() => "test")
|
||||||
|
)
|
||||||
|
|
||||||
|
const spy = await createScheduled("remove-scheduled", {
|
||||||
|
cron: "* * * * * *",
|
||||||
|
})
|
||||||
|
await jest.runOnlyPendingTimersAsync()
|
||||||
|
expect(spy).toHaveBeenCalledTimes(1)
|
||||||
|
expect(spy).toHaveReturnedWith(
|
||||||
|
expect.objectContaining({ output: { testValue: "test" } })
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
it("should fetch an idempotent workflow after its completion", async () => {
|
it("should fetch an idempotent workflow after its completion", async () => {
|
||||||
const { transaction: firstRun } = await workflowOrcModule.run(
|
const { transaction: firstRun } = await workflowOrcModule.run(
|
||||||
"workflow_idempotent",
|
"workflow_idempotent",
|
||||||
|
|||||||
@@ -80,13 +80,17 @@ const AnySubscriber = "any"
|
|||||||
|
|
||||||
export class WorkflowOrchestratorService {
|
export class WorkflowOrchestratorService {
|
||||||
private subscribers: Subscribers = new Map()
|
private subscribers: Subscribers = new Map()
|
||||||
|
private container_: MedusaContainer
|
||||||
|
|
||||||
constructor({
|
constructor({
|
||||||
inMemoryDistributedTransactionStorage,
|
inMemoryDistributedTransactionStorage,
|
||||||
|
sharedContainer,
|
||||||
}: {
|
}: {
|
||||||
inMemoryDistributedTransactionStorage: InMemoryDistributedTransactionStorage
|
inMemoryDistributedTransactionStorage: InMemoryDistributedTransactionStorage
|
||||||
workflowOrchestratorService: WorkflowOrchestratorService
|
workflowOrchestratorService: WorkflowOrchestratorService
|
||||||
|
sharedContainer: MedusaContainer
|
||||||
}) {
|
}) {
|
||||||
|
this.container_ = sharedContainer
|
||||||
inMemoryDistributedTransactionStorage.setWorkflowOrchestratorService(this)
|
inMemoryDistributedTransactionStorage.setWorkflowOrchestratorService(this)
|
||||||
DistributedTransaction.setStorage(inMemoryDistributedTransactionStorage)
|
DistributedTransaction.setStorage(inMemoryDistributedTransactionStorage)
|
||||||
WorkflowScheduler.setStorage(inMemoryDistributedTransactionStorage)
|
WorkflowScheduler.setStorage(inMemoryDistributedTransactionStorage)
|
||||||
@@ -136,7 +140,9 @@ export class WorkflowOrchestratorService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const ret = await flow.run({
|
const ret = await flow.run({
|
||||||
input,
|
input,
|
||||||
@@ -191,7 +197,9 @@ export class WorkflowOrchestratorService {
|
|||||||
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const transaction = await flow.getRunningTransaction(transactionId, context)
|
const transaction = await flow.getRunningTransaction(transactionId, context)
|
||||||
|
|
||||||
@@ -227,7 +235,9 @@ export class WorkflowOrchestratorService {
|
|||||||
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const events = this.buildWorkflowEvents({
|
const events = this.buildWorkflowEvents({
|
||||||
customEventHandlers: eventHandlers,
|
customEventHandlers: eventHandlers,
|
||||||
@@ -287,7 +297,9 @@ export class WorkflowOrchestratorService {
|
|||||||
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const events = this.buildWorkflowEvents({
|
const events = this.buildWorkflowEvents({
|
||||||
customEventHandlers: eventHandlers,
|
customEventHandlers: eventHandlers,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {
|
|||||||
Context,
|
Context,
|
||||||
DAL,
|
DAL,
|
||||||
InternalModuleDeclaration,
|
InternalModuleDeclaration,
|
||||||
|
MedusaContainer,
|
||||||
ModulesSdkTypes,
|
ModulesSdkTypes,
|
||||||
WorkflowsSdkTypes,
|
WorkflowsSdkTypes,
|
||||||
} from "@medusajs/types"
|
} from "@medusajs/types"
|
||||||
@@ -31,6 +32,7 @@ export class WorkflowsModuleService<
|
|||||||
protected baseRepository_: DAL.RepositoryService
|
protected baseRepository_: DAL.RepositoryService
|
||||||
protected workflowExecutionService_: ModulesSdkTypes.IMedusaInternalService<TWorkflowExecution>
|
protected workflowExecutionService_: ModulesSdkTypes.IMedusaInternalService<TWorkflowExecution>
|
||||||
protected workflowOrchestratorService_: WorkflowOrchestratorService
|
protected workflowOrchestratorService_: WorkflowOrchestratorService
|
||||||
|
protected container_: MedusaContainer
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-2
@@ -6,8 +6,10 @@ import {
|
|||||||
} from "@medusajs/workflows-sdk"
|
} from "@medusajs/workflows-sdk"
|
||||||
|
|
||||||
export const createScheduled = (name: string, schedule?: SchedulerOptions) => {
|
export const createScheduled = (name: string, schedule?: SchedulerOptions) => {
|
||||||
const workflowScheduledStepInvoke = jest.fn((input, context) => {
|
const workflowScheduledStepInvoke = jest.fn((input, { container }) => {
|
||||||
return new StepResponse({})
|
return new StepResponse({
|
||||||
|
testValue: container.resolve("test-value"),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const step = createStep("step_1", workflowScheduledStepInvoke)
|
const step = createStep("step_1", workflowScheduledStepInvoke)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
TransactionHandlerType,
|
TransactionHandlerType,
|
||||||
TransactionStepState,
|
TransactionStepState,
|
||||||
} from "@medusajs/utils"
|
} from "@medusajs/utils"
|
||||||
import { asValue } from "awilix"
|
import { asFunction, asValue } from "awilix"
|
||||||
import { knex } from "knex"
|
import { knex } from "knex"
|
||||||
import { setTimeout } from "timers/promises"
|
import { setTimeout } from "timers/promises"
|
||||||
import "../__fixtures__"
|
import "../__fixtures__"
|
||||||
@@ -54,6 +54,7 @@ describe("Workflow Orchestrator module", function () {
|
|||||||
query: remoteQuery,
|
query: remoteQuery,
|
||||||
modules,
|
modules,
|
||||||
sharedContainer,
|
sharedContainer,
|
||||||
|
onApplicationStart,
|
||||||
} = await MedusaApp({
|
} = await MedusaApp({
|
||||||
sharedContainer: container,
|
sharedContainer: container,
|
||||||
sharedResourcesConfig: {
|
sharedResourcesConfig: {
|
||||||
@@ -73,6 +74,8 @@ describe("Workflow Orchestrator module", function () {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await onApplicationStart()
|
||||||
|
|
||||||
query = remoteQuery
|
query = remoteQuery
|
||||||
sharedContainer_ = sharedContainer!
|
sharedContainer_ = sharedContainer!
|
||||||
|
|
||||||
@@ -381,5 +384,21 @@ describe("Workflow Orchestrator module", function () {
|
|||||||
"Tried to execute a scheduled workflow with ID remove-scheduled that does not exist, removing it from the scheduler."
|
"Tried to execute a scheduled workflow with ID remove-scheduled that does not exist, removing it from the scheduler."
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("the scheduled workflow should have access to the shared container", async () => {
|
||||||
|
sharedContainer_.register(
|
||||||
|
"test-value",
|
||||||
|
asFunction(() => "test")
|
||||||
|
)
|
||||||
|
|
||||||
|
const spy = await createScheduled("remove-scheduled", {
|
||||||
|
cron: "* * * * * *",
|
||||||
|
})
|
||||||
|
await setTimeout(1100)
|
||||||
|
expect(spy).toHaveBeenCalledTimes(1)
|
||||||
|
expect(spy).toHaveReturnedWith(
|
||||||
|
expect.objectContaining({ output: { testValue: "test" } })
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ export class WorkflowOrchestratorService {
|
|||||||
private instanceId = ulid()
|
private instanceId = ulid()
|
||||||
protected redisPublisher: Redis
|
protected redisPublisher: Redis
|
||||||
protected redisSubscriber: Redis
|
protected redisSubscriber: Redis
|
||||||
|
protected container_: MedusaContainer
|
||||||
private subscribers: Subscribers = new Map()
|
private subscribers: Subscribers = new Map()
|
||||||
private activeStepsCount: number = 0
|
private activeStepsCount: number = 0
|
||||||
private logger: Logger
|
private logger: Logger
|
||||||
@@ -95,6 +96,7 @@ export class WorkflowOrchestratorService {
|
|||||||
redisPublisher,
|
redisPublisher,
|
||||||
redisSubscriber,
|
redisSubscriber,
|
||||||
logger,
|
logger,
|
||||||
|
sharedContainer,
|
||||||
}: {
|
}: {
|
||||||
dataLoaderOnly: boolean
|
dataLoaderOnly: boolean
|
||||||
redisDistributedTransactionStorage: RedisDistributedTransactionStorage
|
redisDistributedTransactionStorage: RedisDistributedTransactionStorage
|
||||||
@@ -102,7 +104,9 @@ export class WorkflowOrchestratorService {
|
|||||||
redisPublisher: Redis
|
redisPublisher: Redis
|
||||||
redisSubscriber: Redis
|
redisSubscriber: Redis
|
||||||
logger: Logger
|
logger: Logger
|
||||||
|
sharedContainer: MedusaContainer
|
||||||
}) {
|
}) {
|
||||||
|
this.container_ = sharedContainer
|
||||||
this.redisPublisher = redisPublisher
|
this.redisPublisher = redisPublisher
|
||||||
this.redisSubscriber = redisSubscriber
|
this.redisSubscriber = redisSubscriber
|
||||||
this.logger = logger
|
this.logger = logger
|
||||||
@@ -137,6 +141,10 @@ export class WorkflowOrchestratorService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onApplicationStart() {
|
||||||
|
await this.redisDistributedTransactionStorage_.onApplicationStart()
|
||||||
|
}
|
||||||
|
|
||||||
@InjectSharedContext()
|
@InjectSharedContext()
|
||||||
async run<T = unknown>(
|
async run<T = unknown>(
|
||||||
workflowIdOrWorkflow: string | ReturnWorkflow<any, any, any>,
|
workflowIdOrWorkflow: string | ReturnWorkflow<any, any, any>,
|
||||||
@@ -175,7 +183,9 @@ export class WorkflowOrchestratorService {
|
|||||||
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const ret = await flow.run({
|
const ret = await flow.run({
|
||||||
input,
|
input,
|
||||||
@@ -230,7 +240,9 @@ export class WorkflowOrchestratorService {
|
|||||||
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const transaction = await flow.getRunningTransaction(transactionId, context)
|
const transaction = await flow.getRunningTransaction(transactionId, context)
|
||||||
|
|
||||||
@@ -266,7 +278,9 @@ export class WorkflowOrchestratorService {
|
|||||||
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const events = this.buildWorkflowEvents({
|
const events = this.buildWorkflowEvents({
|
||||||
customEventHandlers: eventHandlers,
|
customEventHandlers: eventHandlers,
|
||||||
@@ -326,7 +340,9 @@ export class WorkflowOrchestratorService {
|
|||||||
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
throw new Error(`Workflow with id "${workflowId}" not found.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const flow = exportedWorkflow(container as MedusaContainer)
|
const flow = exportedWorkflow(
|
||||||
|
(container as MedusaContainer) ?? this.container_
|
||||||
|
)
|
||||||
|
|
||||||
const events = this.buildWorkflowEvents({
|
const events = this.buildWorkflowEvents({
|
||||||
customEventHandlers: eventHandlers,
|
customEventHandlers: eventHandlers,
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ export class WorkflowsModuleService<
|
|||||||
onApplicationPrepareShutdown: async () => {
|
onApplicationPrepareShutdown: async () => {
|
||||||
await this.workflowOrchestratorService_.onApplicationPrepareShutdown()
|
await this.workflowOrchestratorService_.onApplicationPrepareShutdown()
|
||||||
},
|
},
|
||||||
|
onApplicationStart: async () => {
|
||||||
|
await this.workflowOrchestratorService_.onApplicationStart()
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@InjectSharedContext()
|
@InjectSharedContext()
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ export class RedisDistributedTransactionStorage
|
|||||||
private workflowOrchestratorService_: WorkflowOrchestratorService
|
private workflowOrchestratorService_: WorkflowOrchestratorService
|
||||||
|
|
||||||
private redisClient: Redis
|
private redisClient: Redis
|
||||||
|
private redisWorkerConnection: Redis
|
||||||
|
private queueName: string
|
||||||
private queue: Queue
|
private queue: Queue
|
||||||
private worker: Worker
|
private worker: Worker
|
||||||
|
|
||||||
@@ -47,12 +49,24 @@ export class RedisDistributedTransactionStorage
|
|||||||
}) {
|
}) {
|
||||||
this.workflowExecutionService_ = workflowExecutionService
|
this.workflowExecutionService_ = workflowExecutionService
|
||||||
this.logger_ = logger
|
this.logger_ = logger
|
||||||
|
|
||||||
this.redisClient = redisConnection
|
this.redisClient = redisConnection
|
||||||
|
this.redisWorkerConnection = redisWorkerConnection
|
||||||
|
this.queueName = redisQueueName
|
||||||
this.queue = new Queue(redisQueueName, { connection: this.redisClient })
|
this.queue = new Queue(redisQueueName, { connection: this.redisClient })
|
||||||
|
}
|
||||||
|
|
||||||
|
async onApplicationPrepareShutdown() {
|
||||||
|
// Close worker gracefully, i.e. wait for the current jobs to finish
|
||||||
|
await this.worker.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
async onApplicationShutdown() {
|
||||||
|
await this.queue.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
async onApplicationStart() {
|
||||||
this.worker = new Worker(
|
this.worker = new Worker(
|
||||||
redisQueueName,
|
this.queueName,
|
||||||
async (job) => {
|
async (job) => {
|
||||||
const allJobs = [
|
const allJobs = [
|
||||||
JobType.RETRY,
|
JobType.RETRY,
|
||||||
@@ -75,19 +89,10 @@ export class RedisDistributedTransactionStorage
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ connection: redisWorkerConnection }
|
{ connection: this.redisWorkerConnection }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async onApplicationPrepareShutdown() {
|
|
||||||
// Close worker gracefully, i.e. wait for the current jobs to finish
|
|
||||||
await this.worker.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
async onApplicationShutdown() {
|
|
||||||
await this.queue.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
setWorkflowOrchestratorService(workflowOrchestratorService) {
|
setWorkflowOrchestratorService(workflowOrchestratorService) {
|
||||||
this.workflowOrchestratorService_ = workflowOrchestratorService
|
this.workflowOrchestratorService_ = workflowOrchestratorService
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user