From a1bf0769774b335af1df94e05a01f3c905fdcd07 Mon Sep 17 00:00:00 2001 From: Alexey Zinoviev Date: Mon, 17 Feb 2025 17:44:23 +0400 Subject: [PATCH] uberf-9428: migrate accounts with multiple active services (#8027) Signed-off-by: Alexey Zinoviev --- server/account-service/src/index.ts | 1 + .../src/migration/migration.ts | 32 +++++++++++++++++-- server/account-service/src/migration/types.ts | 1 + 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/server/account-service/src/index.ts b/server/account-service/src/index.ts index 268b663bc3..c5aa2c79f8 100644 --- a/server/account-service/src/index.ts +++ b/server/account-service/src/index.ts @@ -102,6 +102,7 @@ export function serveAccount (measureCtx: MeasureContext, brandings: BrandingMap const migrations = accountsDb.then(async ([db]) => { if (oldAccsUrl !== undefined) { await migrateFromOldAccounts(oldAccsUrl, db) + console.log('Migrations verified/done') } }) diff --git a/server/account-service/src/migration/migration.ts b/server/account-service/src/migration/migration.ts index d29c515d6c..c1110fde82 100644 --- a/server/account-service/src/migration/migration.ts +++ b/server/account-service/src/migration/migration.ts @@ -23,18 +23,41 @@ import { import { type AccountDB, createAccount } from '@hcengineering/account' import { getMongoAccountDB } from './utils' import { type Account as OldAccount, type Workspace as OldWorkspace } from './types' +import { type MongoAccountDB } from './collections/mongo' + +async function shouldMigrate (oldAccountDb: MongoAccountDB, migrationKey: string): Promise { + while (true) { + const migration = await oldAccountDb.migration.findOne({ key: migrationKey }) + if (migration?.completed === true) { + return false + } + + if (migration?.lastProcessedTime === undefined || Date.now() - migration.lastProcessedTime > 1000 * 15) { + return true + } + + console.log('Migration of accounts database from old accounts is still in progress, waiting...') + await new Promise((resolve) => setTimeout(resolve, 5000)) + } +} export async function migrateFromOldAccounts (oldAccsUrl: string, accountDB: AccountDB): Promise { const migrationKey = 'migrate-from-old-accounts' // Check if old accounts exist const [oldAccountDb, closeOldDb] = await getMongoAccountDB(oldAccsUrl) + let processingHandle try { - const migration = await oldAccountDb.migration.findOne({ key: migrationKey }) - if (migration?.completed === true) { + if (!(await shouldMigrate(oldAccountDb, migrationKey))) { return } + await oldAccountDb.migration.insertOne({ key: migrationKey, completed: false, lastProcessedTime: Date.now() }) + + processingHandle = setInterval(() => { + void oldAccountDb.migration.updateOne({ key: migrationKey }, { lastProcessedTime: Date.now() }) + }, 1000 * 5) + // Mapping between const accountsIdToUuid: Record = {} // Mapping between @@ -131,9 +154,12 @@ export async function migrateFromOldAccounts (oldAccsUrl: string, accountDB: Acc } console.log('Total invites processed:', invitesProcessed) - await oldAccountDb.migration.insertOne({ key: migrationKey, completed: true }) + await oldAccountDb.migration.updateOne({ key: migrationKey }, { completed: true }) console.log('Migration of accounts database from old accounts COMPLETED') } finally { + if (processingHandle !== undefined) { + clearTimeout(processingHandle) + } closeOldDb() } } diff --git a/server/account-service/src/migration/types.ts b/server/account-service/src/migration/types.ts index 86200c47e4..c1e99792de 100644 --- a/server/account-service/src/migration/types.ts +++ b/server/account-service/src/migration/types.ts @@ -174,6 +174,7 @@ export interface UpgradeStatistic { export interface Migration { key: string completed: boolean + lastProcessedTime: number } interface Operator {