diff --git a/common/scripts/version.txt b/common/scripts/version.txt index 8214af1f314..c291b576509 100644 --- a/common/scripts/version.txt +++ b/common/scripts/version.txt @@ -1 +1 @@ -"0.7.410" +"0.7.419" diff --git a/foundations/core/packages/core/src/classes.ts b/foundations/core/packages/core/src/classes.ts index dc242de9281..c9db96401ad 100644 --- a/foundations/core/packages/core/src/classes.ts +++ b/foundations/core/packages/core/src/classes.ts @@ -668,6 +668,7 @@ export interface Version extends Doc { export interface MigrationState extends Doc { plugin: string state: string + durationMs?: number } /** diff --git a/foundations/core/packages/model/src/migration.ts b/foundations/core/packages/model/src/migration.ts index 0c97d1ebb04..c82b8c2eaf5 100644 --- a/foundations/core/packages/model/src/migration.ts +++ b/foundations/core/packages/model/src/migration.ts @@ -176,22 +176,28 @@ export async function tryMigrate ( const states = client.migrateState.get(plugin) ?? new Set() for (const migration of migrations) { if (states.has(migration.state)) continue - if (migration.mode == null || migration.mode === mode) { - try { - client.logger.log('running migration', { plugin, state: migration.state }) - await migration.func(client, mode) - } catch (err: any) { - client.logger.error('Failed to run migration', { plugin, state: migration.state, err }) - Analytics.handleError(err) - continue - } + // Do not persist MigrationState when this migration is not applicable to the + // current mode — otherwise it would be skipped forever on the correct mode. + if (migration.mode != null && migration.mode !== mode) { + continue + } + const startedAt = Date.now() + try { + client.logger.log('running migration', { plugin, state: migration.state }) + await migration.func(client, mode) + } catch (err: any) { + client.logger.error('Failed to run migration', { plugin, state: migration.state, err }) + Analytics.handleError(err) + continue } + const finishedAt = Date.now() const st: MigrationState = { plugin, state: migration.state, + durationMs: finishedAt - startedAt, space: core.space.Configuration, modifiedBy: core.account.System, - modifiedOn: Date.now(), + modifiedOn: finishedAt, _class: core.class.MigrationState, _id: generateId() } @@ -212,19 +218,23 @@ export async function tryUpgrade ( const states = state.get(plugin) ?? new Set() for (const upgrades of migrations) { if (states.has(upgrades.state)) continue + if (upgrades.mode != null && upgrades.mode !== mode) { + continue + } const _client = await client() - if (upgrades.mode == null || upgrades.mode === mode) { - try { - await upgrades.func(_client, mode) - } catch (err: any) { - console.error(err) - Analytics.handleError(err) - continue - } + const startedAt = Date.now() + try { + await upgrades.func(_client, mode) + } catch (err: any) { + console.error(err) + Analytics.handleError(err) + continue } + const finishedAt = Date.now() const st: Data = { plugin, - state: upgrades.state + state: upgrades.state, + durationMs: finishedAt - startedAt } const tx = new TxOperations(_client, core.account.System) await tx.createDoc(core.class.MigrationState, core.space.Configuration, st) diff --git a/models/core/src/core.ts b/models/core/src/core.ts index 0866c91bb77..02e69d551bf 100644 --- a/models/core/src/core.ts +++ b/models/core/src/core.ts @@ -358,6 +358,7 @@ export class TVersion extends TDoc implements Version { export class TMigrationState extends TDoc implements MigrationState { plugin!: string state!: string + durationMs?: number } @Model(core.class.PluginConfiguration, core.class.Doc, DOMAIN_MODEL)