-
Notifications
You must be signed in to change notification settings - Fork 898
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
Enhanced dependency and references scanning #13995
Enhanced dependency and references scanning #13995
Conversation
5a246fe
to
35da1fa
Compare
Add scanner for scannign dependencies and references of the inventory collections.
Before the saving, we need to scan the inventory collections
Scanning of IventoryCollections that scans for dependendies and refrerences. Based on those, we can change the strategies for finding in the DB to find only refrerenced by doing 1 DB query.
load_from_db method name changed
We don't need to actualize dependendencies per assignement, it's being solved in the separate scanning step.
Custom db finder using a selection
Test that custom finder with scanned references is working
Add an InventoryCollection for VMs crosslinks
Use an InventoryCollection for VMs crosslinks, this reduces number of DB queries from N to 1.
Ancestry associations are not defined in models, we will hardcode them, until there is a better way of a dependency scan.
Autofix rubocop issues
4ab6d12
to
7912ea9
Compare
@miq-bot remove_label wip |
Checked commits Ladas/manageiq@3c17a0b~...7912ea9 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 app/models/manager_refresh/inventory_collection.rb
spec/models/manager_refresh/save_inventory/graph_of_inventory_collections_targeted_refresh_spec.rb
|
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.
the find_in_db
code has me a little intimidated.
But I don't need to understand every line here and the rest of this looks great.
@@ -20,8 +20,7 @@ def configured_systems | |||
inventory_object.hostname = host.name | |||
inventory_object.virtual_instance_ref = host.instance_id | |||
inventory_object.inventory_root_group = persister.inventory_root_groups.lazy_find(host.inventory_id.to_s) | |||
# TODO(lsmola) get rid of direct DB access | |||
inventory_object.counterpart = Vm.find_by(:uid_ems => host.instance_id) | |||
inventory_object.counterpart = persister.vms.lazy_find(host.instance_id) |
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.
reads so much better too
@@ -34,15 +33,13 @@ def configuration_scripts | |||
inventory_object.variables = job_template.extra_vars_hash | |||
inventory_object.inventory_root_group = persister.inventory_root_groups.lazy_find(job_template.inventory_id.to_s) | |||
|
|||
authentications = [] | |||
inventory_object.authentications = [] |
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.
did this change actually do anything?
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.
yeah, so now the scanning is as a separate step and you can do inventory_object.authentications = [] and inventory_object.authentications << xy
before, the dependency scan was done on assignment, so inventory_object.authentications = [] would do the scan, but inventory_object.authentications << xy would not, since you access the [] directly
:model_class => Vm, | ||
:arel => Vm, | ||
:strategy => :local_db_find_references, | ||
:manager_ref => [:uid_ems] |
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.
:mode => :lazy
😄
aka - this looks great
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.
doing non lazy will degrade to SQL query per find, unless you set the references upfront :-(
send("process_strategy_#{strategy_name}") | ||
when :find_missing_in_local_db | ||
when :local_db_cache_all | ||
self.data_collection_finalized = 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.
I'm assuming this means "I actually hit the db"
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 is more a flag for 'no more references are coming' so we can do the query and cache it
@@ -0,0 +1,19 @@ | |||
module ManagerRefresh | |||
class InventoryCollection | |||
class Scanner |
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.
even more classes?
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.
Yes, a class for every problem? :-D I might move this elsewhere, when scanning will turn to more generic preprocessing.
# selected << :type if model_class.new.respond_to? :type | ||
# load_from_db.select(selected).find_each do |record| | ||
|
||
# Use the cached db_data_index only data_collection_finalized?, meaning no new reference can occur |
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.
thanks for this comment - I was just about to ask this very question
# | ||
# @param manager_uuid [String] a manager_uuid of the InventoryObject we search in the local DB | ||
def find_in_db(manager_uuid) | ||
# TODO(lsmola) selected need to contain also :keys used in other InventoryCollections pointing to this one, once |
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.
what does "once we get list of all keys" mean
Not sure why this is commented out and what is needed to uncomment it.
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.
right, this commented code is pretty old actually, I just moved it. It's for the next step when I will track what attributes are being referenced and I will select only those
def association?(key) | ||
# TODO(lsmola) remove this if there will be better dependency scan, probably with transitive dependencies filled | ||
# in a second pass | ||
return true if [:parent, :genelogy_parent].include?(key) |
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.
typo — s/genelogy/genealogy/
Good luck figuring out the consequences :)
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.
hehe, we solve those dependencies manually so hopefully no consequence. :-)
Scanning as a next step allows us to make sure all dependencies are there also we can add scanning of all references, to optimize strategies for finding in DB.
Implements:
https://www.pivotaltracker.com/story/show/139357527