-
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
[Dashboard][Embeddable] Create Explicit Diffing System #121241
[Dashboard][Embeddable] Create Explicit Diffing System #121241
Conversation
Pinging @elastic/kibana-presentation (Team:Presentation) |
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 am in progress of processing the change :D
Co-authored-by: Anton Dosov <[email protected]>
It looks like this will work nicely with our in-progress custom Lens equality function. 👍 |
@elasticmachine merge upstream |
fix map embeddable equality check
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.
maps changes LGTM
code review, tested in chrome.
@elasticmachine merge upstream |
@@ -262,9 +262,13 @@ export const useDashboardAppState = ({ | |||
dashboardBuildContext.$checkForUnsavedChanges, | |||
]) | |||
.pipe(debounceTime(DashboardConstants.CHANGE_CHECK_DEBOUNCE)) | |||
.subscribe((states) => { | |||
.subscribe(async (states) => { |
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.
Because of async
piece, I think we should put this logic into switchMap to avoid race conditions
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.
Good call @Dosant !
I didn't think of it, because the function in its current form is almost synchronous due to the only async piece being the untilEmbeddableLoaded
method which is synchronous unless the dashboard is loading.
That said, this could have easily caused race conditions if a downstream implementation used a long-running task in their diffing method. I added a switchmap operator to the pipe and return when the inner observable is closed. I tested by adding a one second delay to the diff_dashboard_state
function, firing off many changes in quick succession, and ensuring that only the latest changes are diffed.
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.
nit: maybe it can be simpler with wrapping promise into an observable using from
:
stream$.pipe(switchMap((v) => from(op(v)))).subscribe((v) => {
// logic
});
@elasticmachine merge upstream |
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.
Can the embeddable code be refactored such that we don't need a deep comparison? Instead we would only do a quick equality check? Say
const isInputEqual = embeddable.getInput() === newInput
If it is not possible as-is, because on each embeddable state change we need to merge persisted state with the embeddable local UI state, maybe we could separate those two concepts? And then use a quick equality check for those?
const isPersistentInputEqual = embeddable.getPersistentInput() === newPersistentInput
const isStateEqual = embeddable.getState() === newState
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.
AppServices code changes LGTM. We discussed the comments in this PR offline and some of the ways of improving embeddable state management.
Not related to this PR, some ideas for future:
- Remove deep-clone usage in embeddable input.
- Separate embeddable (1) persistable state from (2) UI state.
- Start embeddable working group, to discuss embeddable plugin future improvements.
@elasticmachine merge upstream |
@elasticmachine merge upstream |
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 Succeeded
Metrics [docs]Module Count
Public APIs missing comments
Async chunks
Page load bundle
Unknown metric groupsAPI count
References to deprecated APIs
History
To update your PR or re-run it, just comment with: |
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.
Vis editors changes LGTM. I tested the embeddable functionality in Chrome and it seems to work fine :)
Co-authored-by: Anton Dosov <[email protected]> Co-authored-by: nreese <[email protected]> (cherry picked from commit 944ccf1)
…2668) Co-authored-by: Anton Dosov <[email protected]> Co-authored-by: nreese <[email protected]> (cherry picked from commit 944ccf1)
Co-authored-by: Anton Dosov <[email protected]> Co-authored-by: nreese <[email protected]> (cherry picked from commit 944ccf1) # Conflicts: # src/plugins/dashboard/public/application/lib/diff_dashboard_state.ts # x-pack/plugins/maps/server/plugin.ts
… (#124293) * [Dashboard][Embeddable] Create Explicit Diffing System (#121241) Co-authored-by: Anton Dosov <[email protected]> Co-authored-by: nreese <[email protected]> (cherry picked from commit 944ccf1) # Conflicts: # src/plugins/dashboard/public/application/lib/diff_dashboard_state.ts # x-pack/plugins/maps/server/plugin.ts * type fix * replace ecommerce sample map id
Summary
Fixes #98180
Fixes #117960
This PR creates a new system within the embeddable plugin to provide robust input-diffing capabilities. Instead of the dashboard app diffing all of its state the same way, using Lodash's
isEqual
or equivalent, each child embeddable is in charge of determining whether or not its own current explicit input is equal to another input object given by the dashboard (the last saved state). To implement this, two functions have been added to the generic embeddable:getExplicitInput
- is an explicit function / clarification to the embeddable system which allows embeddables to more easily differentiate between what is their own explicit input, and what is input which was passed to them by a parent. If the embeddable does not have a parent, the results fromgetExplicitInput
andgetInput
should be the same.getExplicitInputIsEqual
- is a diffing function which takes one input object and diffs it against its current explicitInput. The generic embeddable has a generic and fairly comprehensive implementation of this function which should work in most cases. Any embeddable type which has input keys that should be ignored when diffing can override this function.Additionally, as an example of why these new API features are useful, the Maps Embeddable was given an implementation of
getExplicitInputIsEqual
which ignoresmapBuffer
, thus solving #98180.Checklist
Delete any items that are not applicable to this PR.