From 967df825cb31a928c528521e8dc6dec4b80f52f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gast=C3=B3n=20Fournier?= Date: Wed, 18 Jun 2025 17:40:21 +0200 Subject: [PATCH] feat: do not lock until migrations are needed (#10170) --- src/lib/server-impl.ts | 34 +++++++++++++++++++--------------- src/migrator.ts | 22 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/lib/server-impl.ts b/src/lib/server-impl.ts index 54ac5d01b1..21e2cef94a 100644 --- a/src/lib/server-impl.ts +++ b/src/lib/server-impl.ts @@ -1,7 +1,7 @@ import stoppable, { type StoppableServer } from 'stoppable'; import { promisify } from 'util'; import version from './util/version.js'; -import { migrateDb, resetDb } from '../migrator.js'; +import { migrateDb, requiresMigration, resetDb } from '../migrator.js'; import getApp from './app.js'; import type MetricsMonitor from './metrics.js'; import { createMetricsMonitor } from './metrics.js'; @@ -336,21 +336,25 @@ async function start( if (config.db.disableMigration) { logger.info('DB migration: disabled'); } else { - logger.info('DB migration: start'); - if (config.flagResolver.isEnabled('migrationLock')) { - logger.info('Running migration with lock'); - const lock = withDbLock(config.db, { - lockKey: defaultLockKey, - timeout: defaultTimeout, - logger, - }); - await lock(migrateDb)(config); - } else { - logger.info('Running migration without lock'); - await migrateDb(config); - } + if (await requiresMigration(config)) { + logger.info('DB migration: start'); + if (config.flagResolver.isEnabled('migrationLock')) { + logger.info('Running migration with lock'); + const lock = withDbLock(config.db, { + lockKey: defaultLockKey, + timeout: defaultTimeout, + logger, + }); + await lock(migrateDb)(config); + } else { + logger.info('Running migration without lock'); + await migrateDb(config); + } - logger.info('DB migration: end'); + logger.info('DB migration: end'); + } else { + logger.info('DB migration: no migration needed'); + } } } catch (err) { logger.error('Failed to migrate db', err); diff --git a/src/migrator.ts b/src/migrator.ts index 82027b290b..8543cefb98 100644 --- a/src/migrator.ts +++ b/src/migrator.ts @@ -40,6 +40,28 @@ export async function migrateDb( }); } +export async function requiresMigration({ + db, +}: Pick): Promise { + return noDatabaseUrl(async () => { + const custom = { + ...db, + connectionTimeoutMillis: secondsToMilliseconds(10), + }; + + // disable Intellij/WebStorm from setting verbose CLI argument to db-migrator + process.argv = process.argv.filter((it) => !it.includes('--verbose')); + const dbm = getInstance(true, { + cwd: __dirname, + config: { custom }, + env: 'custom', + }); + + const pendingMigrations = await dbm.check(); + return pendingMigrations.length > 0; + }); +} + // This exists to ease testing export async function resetDb({ db }: IUnleashConfig): Promise { return noDatabaseUrl(async () => {