Skip to content
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

Import saved searches first #10740

Merged
merged 2 commits into from
Mar 27, 2017
Merged

Conversation

w33ble
Copy link
Contributor

@w33ble w33ble commented Mar 9, 2017

Closes #7667

When importing saved objects from JSON, those objects are run through the saved object service, which means that visualizations and searches check their fields and other hierarchical requirements. For visualizations, this means that any associated saved searches are looked up on import, and things fail if the required saved search does not exist.

However, all saved objects were imported in parallel, which led to weird race conditions where visualizations would fail to import because their saved searches were not yet finished importing.

screenshot 2017-03-09 13 51 37

With this PR, saved searches are imported before anything else, so this race condition is no longer an issue.


To test, either:

  • Import a large number of saved visualizations that use saved searches via the JSON importer, and keep importing and deleting until you run into the race condition
  • Modify the source to introduce a little delay when importing saved searches

If you are interested in the later, here's a handy diff:

--- a/src/core_plugins/kibana/public/management/sections/objects/_objects.js
+++ b/src/core_plugins/kibana/public/management/sections/objects/_objects.js
@@ -194,7 +194,18 @@ uiModules.get('apps/management')
                 return;
               }
 
-              return service.get()
+              // return service.get()
+              function getDelay() {
+                if (doc._type === 'search') {
+                  return new Promise(resolve => {
+                    setTimeout(resolve, 3000);
+                  });
+                }
+                return Promise.resolve();
+              }
+
+              return getDelay()
+                .then(() => service.get())
                 .then(function (obj) {
                   obj.id = doc._id;
                   return obj.applyESResp(doc)

});
}

const docTypes = docs.reduce((types, doc) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about something like this?

const [searches, other] = _.partition(docs, doc => doc._type === "search")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slick, but that only allows me to create 2 collections. That works for now, but I'm planning to add more exports, and order will become important in those cases too. This structure makes it easy to add more ordered collections.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_.groupBy(docs, doc => {
  switch (doc._type) {
    case 'search':
      return 'searches'
    default:
      return 'other'
  }
})

@ycombinator
Copy link
Contributor

Functionality LGTM. Reviewing code now...

Copy link
Contributor

@ycombinator ycombinator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like @kjbekkelund's suggestion to use _.groupBy. This code is trying to group objects by their type and _.groupBy conveys that more explicitly than docs.reduce.

If you are trying to avoid using lodash, then I'd suggest creating a function named groupDocsByType or something that encapsulates your code. That way, its slightly more obvious what's going on.

@w33ble
Copy link
Contributor Author

w33ble commented Mar 16, 2017

_.groupBy also requires some knowledge about that not-very-often-used lodash method. Plus, our stance is to prefer native methods of helpers. And I don't think the use of _.groupBy makes it any easier to read, most of what I have here is preserved even when using it.

Additionally, _.groupBy doesn't enforce an object structure, so later when the code attempts to iterate over docTypes.searches, that could be undefined if the user is not importing any saved searches.

@ycombinator
Copy link
Contributor

For me, its less about whether we use a native method or a lodash method and more about descriptiveness of the operation. Array.prototype.reduce could be used for a lot of things so, as someone who didn't originally write this code, I'd have to dig into it to figure out what it does. If you could wrap that code in a descriptive helper function like groupDocsByType or something, that would make the code more readable IMO.

Copy link
Contributor

@ycombinator ycombinator left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionality still LGTM and code LGTM as well.

@w33ble w33ble added the v5.2.3 label Mar 17, 2017
@w33ble w33ble assigned Bargs and unassigned stacey-gammon Mar 17, 2017
@Bargs
Copy link
Contributor

Bargs commented Mar 17, 2017

LGTM. One note, since this relies on _type it might need to be updated for 6.0 when we decide how to migrate the .kibana index away from types.

@Bargs Bargs removed their assignment Mar 17, 2017
@w33ble
Copy link
Contributor Author

w33ble commented Mar 27, 2017

@Bargs just seeing your comment now, sorry. Isn't that going to be a 7.0 concern? Either way, yeah, it's part of a larger change. This at least makes things work better right now.

@Bargs
Copy link
Contributor

Bargs commented Mar 27, 2017

It'll be a 6.0 thing because new indices will only be able to have one type in 6.0 elastic/elasticsearch#15613 (comment)

@w33ble w33ble merged commit 059864f into elastic:master Mar 27, 2017
w33ble added a commit that referenced this pull request Mar 27, 2017
* import saved searches first

* move saved object type grouping into a helper
w33ble added a commit to w33ble/kibana that referenced this pull request Mar 27, 2017
* import saved searches first
* move saved object type grouping into a helper
w33ble added a commit that referenced this pull request Mar 27, 2017
* import saved searches first
* move saved object type grouping into a helper
w33ble added a commit to w33ble/kibana that referenced this pull request Mar 27, 2017
* import saved searches first
* move saved object type grouping into a helper
w33ble added a commit that referenced this pull request Mar 28, 2017
* import saved searches first
* move saved object type grouping into a helper
@w33ble
Copy link
Contributor Author

w33ble commented Mar 28, 2017

5.x ba92d47
5.3 2473029
5.2 42b925f
5.1 6cee4ec

simianhacker pushed a commit to simianhacker/kibana that referenced this pull request Mar 28, 2017
* import saved searches first

* move saved object type grouping into a helper
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Kibana 4.5.0 object doesn't exists error on import (everything). Order matters?
7 participants