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 09:22:29 -03:00
committed by GitHub
co-authored by Sebastian Rindom Riqwan Thamir
parent 0c0b425de7
commit 8fd1488938
20 changed files with 234 additions and 76 deletions
+10 -3
View File
@@ -4,7 +4,11 @@ import {
MedusaModuleConfig,
ModuleJoinerConfig,
} from "@medusajs/modules-sdk"
import { ContainerRegistrationKeys, ModulesSdkUtils } from "@medusajs/utils"
import {
ContainerRegistrationKeys,
ModulesSdkUtils,
promiseAll,
} from "@medusajs/utils"
export interface InitModulesOptions {
injectedDependencies?: Record<string, unknown>
@@ -48,8 +52,11 @@ export async function initModules({
async function shutdown() {
if (shouldDestroyConnectionAutomatically) {
await (sharedPgConnection as any).context?.destroy()
await (sharedPgConnection as any).destroy()
await promiseAll([
(sharedPgConnection as any).context?.destroy(),
(sharedPgConnection as any).destroy(),
medusaApp.onApplicationShutdown(),
])
} else {
if (!preventConnectionDestroyWarning) {
console.info(
@@ -1,7 +1,8 @@
const path = require("path")
const express = require("express")
const getPort = require("get-port")
const { isObject } = require("@medusajs/utils")
const { isObject, promiseAll } = require("@medusajs/utils")
const { GracefulShutdownServer } = require("medusa-core-utils")
async function bootstrapApp({ cwd, env = {} } = {}) {
const app = express()
@@ -12,20 +13,17 @@ async function bootstrapApp({ cwd, env = {} } = {}) {
const loaders = require("@medusajs/medusa/dist/loaders").default
const { container, dbConnection, pgConnection, disposeResources } =
await loaders({
directory: path.resolve(cwd || process.cwd()),
expressApp: app,
isTest: false,
})
const { container, shutdown } = await loaders({
directory: path.resolve(cwd || process.cwd()),
expressApp: app,
isTest: false,
})
const PORT = await getPort()
return {
disposeResources,
shutdown,
container,
db: dbConnection,
pgConnection,
app,
port: PORT,
}
@@ -37,10 +35,16 @@ module.exports = {
env = {},
skipExpressListen = false,
} = {}) => {
const { app, port, container, db, pgConnection } = await bootstrapApp({
const {
app,
port,
container,
shutdown: medusaShutdown,
} = await bootstrapApp({
cwd,
env,
})
let expressServer
if (skipExpressListen) {
@@ -48,13 +52,7 @@ module.exports = {
}
const shutdown = async () => {
await Promise.all([
container.dispose(),
expressServer.close(),
db?.destroy(),
pgConnection?.context?.destroy(),
container.dispose(),
])
await promiseAll([expressServer.shutdown(), medusaShutdown()])
if (typeof global !== "undefined" && global?.gc) {
global.gc()
@@ -62,7 +60,7 @@ module.exports = {
}
return await new Promise((resolve, reject) => {
expressServer = app.listen(port, async (err) => {
const server = app.listen(port, async (err) => {
if (err) {
await shutdown()
return reject(err)
@@ -74,6 +72,8 @@ module.exports = {
port,
})
})
expressServer = GracefulShutdownServer.create(server)
})
},
}
@@ -54,6 +54,7 @@ const dbTestUtilFactory = (): any => ({
shutdown: async function (dbName: string) {
await this.db_?.destroy()
await this.pgConnection_?.context?.destroy()
await this.pgConnection_?.destroy()
return await dropDatabase(
{ databaseName: dbName, errorIfNonExist: false },
@@ -116,7 +117,7 @@ export function medusaIntegrationTestRunner({
const cwd = process.cwd()
let shutdown: () => Promise<void>
let shutdown = async () => void 0
let dbUtils = dbTestUtilFactory()
let container: ContainerLike
let apiUtils: any
@@ -142,6 +143,8 @@ export function medusaIntegrationTestRunner({
getContainer: () => container,
} as MedusaSuiteOptions
let isFirstTime = true
const beforeAll_ = async () => {
await dbUtils.create(dbName)
const { dbDataSource, pgConnection } = await initDb({
@@ -156,7 +159,7 @@ export function medusaIntegrationTestRunner({
dbUtils.pgConnection_ = pgConnection
const {
shutdown: shutdown_,
shutdown: serverShutdown,
container: container_,
port,
} = await startBootstrapApp({
@@ -164,13 +167,26 @@ export function medusaIntegrationTestRunner({
env,
})
apiUtils = axios.create({ baseURL: `http://localhost:${port}` })
const cancelTokenSource = axios.CancelToken.source()
apiUtils = axios.create({
baseURL: `http://localhost:${port}`,
cancelToken: cancelTokenSource.token,
})
container = container_
shutdown = shutdown_
shutdown = async () => {
await serverShutdown()
cancelTokenSource.cancel("Request canceled by shutdown")
}
}
const beforeEach_ = async () => {
// The beforeAll already run everything, so lets not re run the loaders for the first iteration
if (isFirstTime) {
isFirstTime = false
return
}
const container = options.getContainer()
const copiedContainer = createMedusaContainer({}, container)