-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve migration perf #99773
Improve migration perf #99773
Conversation
Pinging @elastic/kibana-core (Team:Core) |
let stateP: State = cloneDeep(currentState); | ||
let stateP: State = currentState; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure our state workflow is pure enough for this to not have any side effect? (should be but still asking)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be a red herring:
We are risking that any step might call stateP.logs.push()
. So far, I found that we are using everywhere stateP.logs = [...stateP.logs, {...}]
, so we should be fine...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure our state workflow is pure enough for this to not have any side effect? (should be but still asking)
@pgayvallet I'm not quite sure cloneDeep
usage is justified here.
Mutations made during model
execution will be returned from the model
and State will be cloned with mutations during the next model
call.
The only difference is the OldState
mutation won't affect NewState
shape. But AFAIK SavedObjectMigrationFn
is the only valid case for mutations and we already clone the doc
during migrateAndConvert
call.
const clonedDoc = _.cloneDeep(doc); |
I'm fine to roll back the change. In this case, we will pay the penalty of deep cloning all the SO several times. Plus additional work for GC.
We are risking that any step might call stateP.logs.push()
@afharo Can stateP.logs.push
be called with the current implementation? I think so. stateP.logs
is not an immutable array, State
is not frozen object (not sure why, btw)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not quite sure cloneDeep usage is justified here.
After a quick look, I don't think either. Also we're supposed to have unit tests covering these things, so I think we're fine keeping the change.
@@ -370,7 +370,7 @@ export interface LegacyDeleteState extends LegacyBaseState { | |||
readonly controlState: 'LEGACY_DELETE'; | |||
} | |||
|
|||
export type State = | |||
export type State = Readonly< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note: It's not RecursiveReadonly<...>
but we can add it to make sure State is not mutated
@@ -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; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not surprising given that <7.3
needed to be parsed and interpreted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Presentation team changes LGTM - Code only review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@elasticmachine merge upstream |
@elasticmachine merge upstream |
💚 Build SucceededMetrics [docs]Module Count
Async chunks
Page load bundle
Unknown metric groupsReferences to deprecated APIs
History
To update your PR or re-run it, just comment with: |
* 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]>
* 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]> Co-authored-by: Kibana Machine <[email protected]>
* 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]>
Summary
Part of #92933
While working on SO migrations I noticed a couple of low-hanging fruits improving migration performance.
Testing performed on https://github.com/elastic/kibana/blob/master/src/core/server/saved_objects/migrationsv2/integration_tests/archives/7.7.2_xpack_100k_obj.zip data set as we needed any reproducible source of a large number of SO.
Most of the time Kibana spends on transforming SO POJO (considering I run the test locally with the minimal network overhead) so I removed a few expensive operations:
model
call. State shouldn't be mutated during migration by design. See the discussion below Improve migration perf #99773 (comment)It allowed Kibana to reduce migration time for the 100k test data set by ~16% from
99.6sec
to83.536sec
.Checklist