Skip to content

Commit

Permalink
Improve migration perf (#99773)
Browse files Browse the repository at this point in the history
* Do not clone state, use TypeCheck it's not mutated

* do not recreate context for every migration

* use more optional semver check

* update SavedObjectMigrationContext type

* add a test model returns new state object

* update docs

Co-authored-by: Kibana Machine <[email protected]>
  • Loading branch information
mshustov and kibanamachine authored May 17, 2021
1 parent 5e410f5 commit d8a2f8f
Show file tree
Hide file tree
Showing 10 changed files with 47 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ The version in which this object type is being converted to a multi-namespace ty
<b>Signature:</b>

```typescript
convertToMultiNamespaceTypeVersion?: string;
readonly convertToMultiNamespaceTypeVersion?: string;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ logger instance to be used by the migration handler
<b>Signature:</b>

```typescript
log: SavedObjectsMigrationLogger;
readonly log: SavedObjectsMigrationLogger;
```
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ The migration version that this migration function is defined for
<b>Signature:</b>

```typescript
migrationVersion: string;
readonly migrationVersion: string;
```
Original file line number Diff line number Diff line change
Expand Up @@ -661,13 +661,14 @@ function wrapWithTry(
migrationFn: SavedObjectMigrationFn,
log: Logger
) {
const context = Object.freeze({
log: new MigrationLogger(log),
migrationVersion: version,
convertToMultiNamespaceTypeVersion: type.convertToMultiNamespaceTypeVersion,
});

return function tryTransformDoc(doc: SavedObjectUnsanitizedDoc) {
try {
const context = {
log: new MigrationLogger(log),
migrationVersion: version,
convertToMultiNamespaceTypeVersion: type.convertToMultiNamespaceTypeVersion,
};
const result = migrationFn(doc, context);

// A basic sanity check to help migration authors detect basic errors
Expand Down
6 changes: 3 additions & 3 deletions src/core/server/saved_objects/migrations/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,15 @@ export interface SavedObjectMigrationContext {
/**
* logger instance to be used by the migration handler
*/
log: SavedObjectsMigrationLogger;
readonly log: SavedObjectsMigrationLogger;
/**
* The migration version that this migration function is defined for
*/
migrationVersion: string;
readonly migrationVersion: string;
/**
* The version in which this object type is being converted to a multi-namespace type
*/
convertToMultiNamespaceTypeVersion?: string;
readonly convertToMultiNamespaceTypeVersion?: string;
}

/**
Expand Down
25 changes: 25 additions & 0 deletions src/core/server/saved_objects/migrationsv2/model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,31 @@ describe('migrations v2 model', () => {
});

describe('model transitions from', () => {
it('transition returns new state', () => {
const initState: State = {
...baseState,
controlState: 'INIT',
currentAlias: '.kibana',
versionAlias: '.kibana_7.11.0',
versionIndex: '.kibana_7.11.0_001',
};

const res: ResponseType<'INIT'> = Either.right({
'.kibana_7.11.0_001': {
aliases: {
'.kibana': {},
'.kibana_7.11.0': {},
},
mappings: {
properties: {},
},
settings: {},
},
});
const newState = model(initState, res);
expect(newState).not.toBe(initState);
});

describe('INIT', () => {
const initState: State = {
...baseState,
Expand Down
4 changes: 2 additions & 2 deletions src/core/server/saved_objects/migrationsv2/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { gt, valid } from 'semver';
import * as Either from 'fp-ts/lib/Either';
import * as Option from 'fp-ts/lib/Option';
import { cloneDeep } from 'lodash';

import { AliasAction, FetchIndexResponse, isLeftTypeof, RetryableEsClientError } from './actions';
import { AllActionStates, InitState, State } from './types';
import { IndexMapping } from '../mappings';
Expand Down Expand Up @@ -187,7 +187,7 @@ export const model = (currentState: State, resW: ResponseType<AllActionStates>):
// control state using:
// `const res = resW as ResponseType<typeof stateP.controlState>;`

let stateP: State = cloneDeep(currentState);
let stateP: State = currentState;

// Handle retryable_es_client_errors. Other left values need to be handled
// by the control state specific code below.
Expand Down
5 changes: 3 additions & 2 deletions src/core/server/saved_objects/migrationsv2/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ export interface LegacyDeleteState extends LegacyBaseState {
readonly controlState: 'LEGACY_DELETE';
}

export type State =
export type State = Readonly<
| FatalState
| InitState
| DoneState
Expand Down Expand Up @@ -411,7 +411,8 @@ export type State =
| LegacySetWriteBlockState
| LegacyReindexState
| LegacyReindexWaitForTaskState
| LegacyDeleteState;
| LegacyDeleteState
>;

export type AllControlStates = State['controlState'];
/**
Expand Down
6 changes: 3 additions & 3 deletions src/core/server/server.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -2152,9 +2152,9 @@ export interface SavedObjectExportBaseOptions {

// @public
export interface SavedObjectMigrationContext {
convertToMultiNamespaceTypeVersion?: string;
log: SavedObjectsMigrationLogger;
migrationVersion: string;
readonly convertToMultiNamespaceTypeVersion?: string;
readonly log: SavedObjectsMigrationLogger;
readonly migrationVersion: string;
}

// @public
Expand Down
5 changes: 2 additions & 3 deletions src/plugins/dashboard/common/saved_dashboard_references.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/

import semverSatisfies from 'semver/functions/satisfies';
import Semver from 'semver';
import { SavedObjectAttributes, SavedObjectReference } from '../../../core/types';
import { DashboardContainerStateWithType, DashboardPanelState } from './types';
import { EmbeddablePersistableStateService } from '../../embeddable/common/types';
Expand All @@ -24,7 +23,7 @@ export interface SavedObjectAttributesAndReferences {
}

const isPre730Panel = (panel: Record<string, string>): boolean => {
return 'version' in panel ? semverSatisfies(panel.version, '<7.3') : true;
return 'version' in panel ? Semver.gt('7.3.0', panel.version) : true;
};

function dashboardAttributesToState(
Expand Down

0 comments on commit d8a2f8f

Please sign in to comment.