From 2bb4e1cedd167da00da82590d686f9c5624da7ea Mon Sep 17 00:00:00 2001 From: olivermrbl Date: Thu, 1 Dec 2022 11:26:51 +0100 Subject: [PATCH 1/6] wip --- .../src/scripts/test-statement-timeout.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 packages/medusa/src/scripts/test-statement-timeout.ts diff --git a/packages/medusa/src/scripts/test-statement-timeout.ts b/packages/medusa/src/scripts/test-statement-timeout.ts new file mode 100644 index 0000000000000..054057d82a9b0 --- /dev/null +++ b/packages/medusa/src/scripts/test-statement-timeout.ts @@ -0,0 +1,54 @@ +import dotenv from "dotenv" +import { createConnection } from "typeorm" +import { default as Logger } from "../loaders/logger" +dotenv.config() + +const typeormConfig = { + type: process.env.TYPEORM_CONNECTION, + url: process.env.TYPEORM_URL, + username: process.env.TYPEORM_USERNAME, + password: process.env.TYPEORM_PASSWORD, + database: process.env.TYPEORM_DATABASE, + migrations: [process.env.TYPEORM_MIGRATIONS as string], + entities: [process.env.TYPEORM_ENTITIES], + logging: true, + maxQueryExecutionTime: 5000, + extra: { + statement_timeout: 5000, + idle_in_transaction_session_timeout: 5000, + }, +} + +const run = async function ({ typeormConfig }) { + const connection = await createConnection(typeormConfig) + console.log(connection.options) + + const queryRunner = connection.createQueryRunner() + await queryRunner.connect() + + try { + await queryRunner.startTransaction() + + const result = await queryRunner.query(`select * from product`) + + await new Promise((resolve) => + setTimeout(() => resolve(console.log("test")), 10000) + ) + + await queryRunner.commitTransaction() + return result + } catch (error) { + console.log(error) + throw error + } finally { + await queryRunner.release() + } +} +run({ typeormConfig }) + .then(() => { + Logger.info("Test run successfull") + process.exit() + }) + .catch((err) => console.log(err)) + +export default run From b9d0165c1b4b396410143a116e3b0d471c4fc05e Mon Sep 17 00:00:00 2001 From: olivermrbl Date: Thu, 1 Dec 2022 11:31:29 +0100 Subject: [PATCH 2/6] add error message --- packages/medusa/src/scripts/test-statement-timeout.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/medusa/src/scripts/test-statement-timeout.ts b/packages/medusa/src/scripts/test-statement-timeout.ts index 054057d82a9b0..a4fc5dd2c356e 100644 --- a/packages/medusa/src/scripts/test-statement-timeout.ts +++ b/packages/medusa/src/scripts/test-statement-timeout.ts @@ -21,7 +21,6 @@ const typeormConfig = { const run = async function ({ typeormConfig }) { const connection = await createConnection(typeormConfig) - console.log(connection.options) const queryRunner = connection.createQueryRunner() await queryRunner.connect() @@ -38,7 +37,9 @@ const run = async function ({ typeormConfig }) { await queryRunner.commitTransaction() return result } catch (error) { - console.log(error) + // Query runner will be released in case the idle session option kicks in + // Therefore, out current error handler already covers the case when the session is idle + // It throws a 409, invalid state throw error } finally { await queryRunner.release() From f3939ee50ed8dae0be041f1eb40061ce20148b2c Mon Sep 17 00:00:00 2001 From: olivermrbl Date: Thu, 1 Dec 2022 11:32:32 +0100 Subject: [PATCH 3/6] wip --- packages/medusa/src/scripts/test-statement-timeout.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/medusa/src/scripts/test-statement-timeout.ts b/packages/medusa/src/scripts/test-statement-timeout.ts index a4fc5dd2c356e..91ec607c5972e 100644 --- a/packages/medusa/src/scripts/test-statement-timeout.ts +++ b/packages/medusa/src/scripts/test-statement-timeout.ts @@ -12,10 +12,8 @@ const typeormConfig = { migrations: [process.env.TYPEORM_MIGRATIONS as string], entities: [process.env.TYPEORM_ENTITIES], logging: true, - maxQueryExecutionTime: 5000, extra: { - statement_timeout: 5000, - idle_in_transaction_session_timeout: 5000, + idle_in_transaction_session_timeout: 2000, }, } @@ -31,7 +29,7 @@ const run = async function ({ typeormConfig }) { const result = await queryRunner.query(`select * from product`) await new Promise((resolve) => - setTimeout(() => resolve(console.log("test")), 10000) + setTimeout(() => resolve(console.log("test")), 3000) ) await queryRunner.commitTransaction() From bf3ff76914ac4d9e03afea85e278331cbbd5ef0b Mon Sep 17 00:00:00 2001 From: olivermrbl Date: Thu, 1 Dec 2022 12:31:34 +0100 Subject: [PATCH 4/6] add integration tests --- .../api/__tests__/database/index.js | 60 +++++++++++++++++++ integration-tests/helpers/use-db.js | 4 +- packages/medusa/src/index.js | 4 +- .../src/scripts/test-statement-timeout.ts | 53 ---------------- 4 files changed, 65 insertions(+), 56 deletions(-) create mode 100644 integration-tests/api/__tests__/database/index.js delete mode 100644 packages/medusa/src/scripts/test-statement-timeout.ts diff --git a/integration-tests/api/__tests__/database/index.js b/integration-tests/api/__tests__/database/index.js new file mode 100644 index 0000000000000..37166131f1359 --- /dev/null +++ b/integration-tests/api/__tests__/database/index.js @@ -0,0 +1,60 @@ +const path = require("path") + +const setupServer = require("../../../helpers/setup-server") +const { initDb, useDb } = require("../../../helpers/use-db") + +jest.setTimeout(30000) + +describe("Database options", () => { + let medusaProcess + let dbConnection + + beforeAll(async () => { + const cwd = path.resolve(path.join(__dirname, "..", "..")) + dbConnection = await initDb({ + cwd, + database_extra: { idle_in_transaction_session_timeout: 2000 }, + }) + medusaProcess = await setupServer({ cwd }) + }) + + afterAll(async () => { + const db = useDb() + await db.shutdown() + medusaProcess.kill() + }) + + describe("idle_in_transaction_session_timeout", () => { + it("Resolves successfully", async () => { + expect.assertions(1) + + let queryRunner + + try { + queryRunner = dbConnection.createQueryRunner() + await queryRunner.connect() + + await queryRunner.startTransaction() + + await queryRunner.query(`select * from product`) + + await new Promise((resolve) => + setTimeout(() => resolve(console.log("")), 4000) + ) + + await queryRunner.commitTransaction() + + if (!queryRunner.isReleased) { + await queryRunner.release() + } + } catch (error) { + // Query runner will be released in case the idle session option kicks in + // Therefore, out current error handler already covers the case when the session is idle + // It throws a 409, invalid state + expect(error?.type || error.name).toEqual( + "QueryRunnerAlreadyReleasedError" + ) + } + }) + }) +}) diff --git a/integration-tests/helpers/use-db.js b/integration-tests/helpers/use-db.js index fb8c10f661feb..4a5f37be64d70 100644 --- a/integration-tests/helpers/use-db.js +++ b/integration-tests/helpers/use-db.js @@ -77,7 +77,7 @@ const DbTestUtil = { const instance = DbTestUtil module.exports = { - initDb: async function ({ cwd }) { + initDb: async function ({ cwd, database_extra }) { const configPath = path.resolve(path.join(cwd, `medusa-config.js`)) const { projectConfig, featureFlags } = require(configPath) @@ -112,6 +112,7 @@ module.exports = { database: projectConfig.database_database, synchronize: true, entities, + extra: database_extra ?? {}, }) instance.setDb(dbConnection) @@ -157,6 +158,7 @@ module.exports = { url: DB_URL, entities: enabledEntities, migrations: enabledMigrations, + extra: database_extra ?? {}, }) await dbConnection.runMigrations() diff --git a/packages/medusa/src/index.js b/packages/medusa/src/index.js index bbef3b1412c63..b676ae142257f 100644 --- a/packages/medusa/src/index.js +++ b/packages/medusa/src/index.js @@ -1,6 +1,6 @@ export * from "./api" export * from "./interfaces" -export * from "./types/price-list" -export * from "./types/batch-job" export * from "./models" export * from "./services" +export * from "./types/batch-job" +export * from "./types/price-list" diff --git a/packages/medusa/src/scripts/test-statement-timeout.ts b/packages/medusa/src/scripts/test-statement-timeout.ts deleted file mode 100644 index 91ec607c5972e..0000000000000 --- a/packages/medusa/src/scripts/test-statement-timeout.ts +++ /dev/null @@ -1,53 +0,0 @@ -import dotenv from "dotenv" -import { createConnection } from "typeorm" -import { default as Logger } from "../loaders/logger" -dotenv.config() - -const typeormConfig = { - type: process.env.TYPEORM_CONNECTION, - url: process.env.TYPEORM_URL, - username: process.env.TYPEORM_USERNAME, - password: process.env.TYPEORM_PASSWORD, - database: process.env.TYPEORM_DATABASE, - migrations: [process.env.TYPEORM_MIGRATIONS as string], - entities: [process.env.TYPEORM_ENTITIES], - logging: true, - extra: { - idle_in_transaction_session_timeout: 2000, - }, -} - -const run = async function ({ typeormConfig }) { - const connection = await createConnection(typeormConfig) - - const queryRunner = connection.createQueryRunner() - await queryRunner.connect() - - try { - await queryRunner.startTransaction() - - const result = await queryRunner.query(`select * from product`) - - await new Promise((resolve) => - setTimeout(() => resolve(console.log("test")), 3000) - ) - - await queryRunner.commitTransaction() - return result - } catch (error) { - // Query runner will be released in case the idle session option kicks in - // Therefore, out current error handler already covers the case when the session is idle - // It throws a 409, invalid state - throw error - } finally { - await queryRunner.release() - } -} -run({ typeormConfig }) - .then(() => { - Logger.info("Test run successfull") - process.exit() - }) - .catch((err) => console.log(err)) - -export default run From bd42c11d1edfdf4f2165e41e3097dc5d8722e5b5 Mon Sep 17 00:00:00 2001 From: olivermrbl Date: Thu, 1 Dec 2022 16:24:15 +0100 Subject: [PATCH 5/6] fix error --- integration-tests/api/__tests__/database/index.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/integration-tests/api/__tests__/database/index.js b/integration-tests/api/__tests__/database/index.js index 37166131f1359..7a86d6f6b701f 100644 --- a/integration-tests/api/__tests__/database/index.js +++ b/integration-tests/api/__tests__/database/index.js @@ -13,7 +13,7 @@ describe("Database options", () => { const cwd = path.resolve(path.join(__dirname, "..", "..")) dbConnection = await initDb({ cwd, - database_extra: { idle_in_transaction_session_timeout: 2000 }, + database_extra: { idle_in_transaction_session_timeout: 1000 }, }) medusaProcess = await setupServer({ cwd }) }) @@ -38,19 +38,15 @@ describe("Database options", () => { await queryRunner.query(`select * from product`) + // Idle time is 1000 ms so this should timeout await new Promise((resolve) => - setTimeout(() => resolve(console.log("")), 4000) + setTimeout(() => resolve(console.log("")), 2000) ) + // This query should fail with a QueryRunnerAlreadyReleasedError await queryRunner.commitTransaction() - - if (!queryRunner.isReleased) { - await queryRunner.release() - } } catch (error) { - // Query runner will be released in case the idle session option kicks in - // Therefore, out current error handler already covers the case when the session is idle - // It throws a 409, invalid state + // Query runner will be released in case idle_in_transaction_session_timeout kicks in expect(error?.type || error.name).toEqual( "QueryRunnerAlreadyReleasedError" ) From 07d762a2976abe9528db63563d19fdb47f18c47f Mon Sep 17 00:00:00 2001 From: Oliver Windall Juhl <59018053+olivermrbl@users.noreply.github.com> Date: Thu, 1 Dec 2022 16:24:54 +0100 Subject: [PATCH 6/6] Create wet-snakes-hide.md --- .changeset/wet-snakes-hide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/wet-snakes-hide.md diff --git a/.changeset/wet-snakes-hide.md b/.changeset/wet-snakes-hide.md new file mode 100644 index 0000000000000..21e160100445d --- /dev/null +++ b/.changeset/wet-snakes-hide.md @@ -0,0 +1,5 @@ +--- +"@medusajs/medusa": patch +--- + +tests(integration-tests): Add integration test suite for database options