chore: medusa shutdown (#6865)

* chore: medusa shutdown

* continue

* use shutdown

* on application shutdown

* consume shutdown

* more connection close

* more cleanup

* more cleanup

* update lock

* revert package

* graceful shutdown

* Create yellow-apples-attack.md

* graceful shutdown

* graceful shutdown

---------

Co-authored-by: Sebastian Rindom <skrindom@gmail.com>
Co-authored-by: Riqwan Thamir <rmthamir@gmail.com>
This commit is contained in:
Adrien de Peretti
2024-03-29 13:22:29 +01:00
committed by GitHub
parent 0c0b425de7
commit 8fd1488938
20 changed files with 234 additions and 76 deletions
@@ -20,7 +20,9 @@ export async function loadInternalModule(
migrationOnly?: boolean,
loaderOnly?: boolean
): Promise<{ error?: Error } | void> {
const registrationName = resolution.definition.registrationName
const registrationName = !loaderOnly
? resolution.definition.registrationName
: resolution.definition.registrationName + "__loaderOnly"
const { resources } =
resolution.moduleDeclaration as InternalModuleDeclaration
@@ -122,11 +124,8 @@ export async function loadInternalModule(
}
}
if (loaderOnly) {
return
}
const moduleService = loadedModule.service
container.register({
[registrationName]: asFunction((cradle) => {
;(moduleService as any).__type = MedusaModuleType
@@ -137,6 +136,12 @@ export async function loadInternalModule(
)
}).singleton(),
})
if (loaderOnly) {
// The expectation is only to run the loader as standalone, so we do not need to register the service and we need to cleanup all services
const service = container.resolve(registrationName)
await service.__hooks?.onApplicationShutdown()
}
}
export async function loadModuleMigrations(
+13 -12
View File
@@ -22,6 +22,7 @@ import {
isObject,
isString,
ModulesSdkUtils,
promiseAll,
} from "@medusajs/utils"
import { asValue } from "awilix"
import {
@@ -202,6 +203,7 @@ export type MedusaAppOutput = {
entitiesMap?: Record<string, any>
notFound?: Record<string, Record<string, string>>
runMigrations: RunMigrationFn
onApplicationShutdown: () => Promise<void>
}
export type MedusaAppOptions = {
@@ -237,19 +239,16 @@ async function MedusaApp_({
migrationOnly = false,
loaderOnly = false,
workerMode = "server",
}: MedusaAppOptions & { migrationOnly?: boolean } = {}): Promise<{
modules: Record<string, LoadedModule | LoadedModule[]>
link: RemoteLink | undefined
query: (
query: string | RemoteJoinerQuery | object,
variables?: Record<string, unknown>,
options?: RemoteJoinerOptions
) => Promise<any>
entitiesMap?: Record<string, any>
notFound?: Record<string, Record<string, string>>
runMigrations: RunMigrationFn
}> {
}: MedusaAppOptions & {
migrationOnly?: boolean
} = {}): Promise<MedusaAppOutput> {
const sharedContainer_ = createMedusaContainer({}, sharedContainer)
const onApplicationShutdown = async () => {
await promiseAll([
MedusaModule.onApplicationShutdown(),
sharedContainer_.dispose(),
])
}
const modules: MedusaModuleConfig =
modulesConfig ??
@@ -312,6 +311,7 @@ async function MedusaApp_({
if (loaderOnly) {
return {
onApplicationShutdown,
modules: allModules,
link: undefined,
query: async () => {
@@ -387,6 +387,7 @@ async function MedusaApp_({
}
return {
onApplicationShutdown,
modules: allModules,
link: remoteLink,
query,
+15
View File
@@ -15,6 +15,7 @@ import {
} from "@medusajs/types"
import {
createMedusaContainer,
promiseAll,
simpleHash,
stringifyCircular,
} from "@medusajs/utils"
@@ -116,6 +117,20 @@ export class MedusaModule {
}
}
}
public static async onApplicationShutdown(): Promise<void> {
await promiseAll(
[...MedusaModule.instances_.values()].map(instances => {
return Object.values(instances).map((instance: IModuleService) => {
return instance.__hooks?.onApplicationShutdown
?.bind(instance)()
.catch(() => {
// The module should handle this and log it
return void 0
})
})
}).flat()
)
}
public static clearInstances(): void {
MedusaModule.instances_.clear()