-
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
De-couple DescendantLoader from Rails #15460
Conversation
Adds a setup method to DescendantLoader that will do the monkey patching necessary on ActiveRecord and ActiveSupport, but only do it once. Also moves the module prepending of ActsAsArModel to that class, since we own it. This allows it to be deferred from loading and applying the DescendantLoader patches until ActsAsArModel is required/needed.
By requiring ActiveRecord in the DescendantLoader, it allows the .setup method to be run by just requiring lib/extensions/descendant_loader.rb. Without it, a "uninitialized constant DescendantLoader::ActiveRecord" error is raised.
Swapping out `Rails` and using the `ManageIQ` lib allows for the DescendantLoader's instance methods to function without Rails, so the following now works: ruby -Ilib -e 'require "extensions/descendant_loader.rb"; DescendantLoader.descendants_paths'
58e21bf
to
cc17416
Compare
Checked commits NickLaMuro/manageiq@2ff8f43~...cc17416 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 |
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.
Looks good @NickLaMuro. Can you update the description with what you're solving? It doesn't really say why you did this. Decoupling is nice but clearly, you tried something in a pure ruby script, it failed, and so you made it work.
I'm curious what was the use case and how much faster and small the process is using this technique vs. a fat rails process. |
@jrafanie This was basically the gist of the rational (already in the description):
I guess to avoid the novel, I was assuming from there someone could have extrapolated that "and to load |
Oh... woops... that ruby script was actually taken from the |
@NickLaMuro @jrafanie what is the status of this PR? |
This PR is complete as far as I am concerned, but it sounds like @jrafanie has some questions, which I feel like I answered already in my PR description. To avoid writing a verbose explanation unless it was truly necessary, I was waiting to see if asking if my PR description was not clear and should be elaborated on. I can explain things further if needed, and added the Pivotal story related to this effort in PR description for context. |
@@ -1,3 +1,5 @@ | |||
require_relative "extensions/descendant_loader.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.
Remove the .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.
I'm concerned that this breaks Rails autoloading, but that concern is probably minor/unwarranted.
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 will look into this.
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.
Following the precedent from my other recent comment:
- Will remove the
.rb
(for some reason I thought it was required... or helped in some way, but nope) - Not sure how I will test the autoloading concern to be honest. Might take me more time to investigate then I probably should at this time, mostly because I only so deep of knowledge on the internal workings of Rails' autoloading that I probably would need to do some spelunking to properly give a "yay" or "nay". I will try and update regardless.
ActiveRecord::Base.singleton_class.send(:prepend, DescendantLoader::ArDescendantsWithLoader) | ||
ActiveSupport::Dependencies.send(:prepend, DescendantLoader::AsDependenciesClearWithLoader) | ||
ActsAsArModel.singleton_class.send(:prepend, DescendantLoader::ArDescendantsWithLoader) | ||
DescendantLoader.setup | ||
|
||
at_exit do |
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.
Technically, this should be part of the setup as well. (The at_exit
I mean, if my comment here was not clear )
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.
Maybe address this comment?
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.
Agreed. Will do. Should have confirmed that I intended to do that originally. Will look into doing this tomorrow.
It sounds like you are trying to not load the Vmdb::Plugins? If so, that doesn't make sense to me. The Vmdb::Plugins provide the models that the DescendantLoader needs to see. If those models aren't loaded, then there's really no point to the DescendantLoader at all. Separately, I'm disliking to the move to the non-Rails That being said, we were also waiting on the manageiq-gems-pending/lib/util directory to be moved into a new gem such that it becomes the new core gem that we can then build on top of. I see the path forward as
|
Poorly constructed sentence on my part I guess, but what I was referring to when I said "so I skipped adding that part" was the omission of adding what was in the quotes to the PR description, and not trying to avoid loading
I don't disagree with this, but: a) I myself am not in charge of this effort, or am around in person where I am sure a majority of these conversations are involved with this, and unless I would have daily conversations with you and/or @chessbyte about it's direction, me working on it would impede it's progress So, while agree this is confusing having two ways of doing the same thing (as you have also stated), but my thought was to move forward in this repo for now until design decisions have been made and are more closely a reality. Also, hopefully when slim workers are in place, we have some tests around them such that if |
Currently on a "New Year's cleanup" of some of my older PRs, and read through this one and made some additions after I re-acclimated myself to what was done here and why. @jrafanie (and I guess @Fryguy as well), I have updated the description to include a "more verbose" section that describes a possible use case for this stuff down the road, and should hopefully address the confusion mentioned in @jrafanie 's comments here and here. #NickLaMuroBookClub2018 That said, I know @Fryguy still probably holds his opinion from above, and which is understandable and I while don't fully disagree with it, I still think this is the simplest way to achieve the motivations behind this PR, but I will add some color thought to that below. That all said, this is not directly related to anything being worked on by myself or anyone else at the moment (as far as I know), and if Jason's comment above is enough to warrant closing this PR, that is fine as I assume my comment below will just be extra noise (and another novel to the archives). So the I will emphasize, though, this is not suggesting we abandon using Rails, just only use it where appropriate (in my opinion, just the UI and API workers as they are today, but that is a larger, more encompassing architectural discussion that I will hold off on having here). I still very much think Going back to the Again, I think moving towards this (or something similar) makes sense in my mind, but if not, we maybe consider undoing what has already been merged since we are sitting in a limbo state at the moment and the debate on whether this is a good idea or not is blocking PRs from being merged/closed. |
I don't know about the words in this PR but I'm fine with the code changes as long as the comments have been addressed. This PR doesn't feel controversial. It's merely a Rails-less alias for the Rails constant. |
This pull request is not mergeable. Please rebase and repush. |
This pull request has been automatically closed because it has not been updated for at least 6 months. Feel free to reopen this pull request if these changes are still valid. Thank you for all your contributions! |
Does the following to allow DescendantLoader to be loaded without a full Rails dependency:
.setup
method.ActsAsArModel
into that file, which then only applies the patch whenActsAsArModel
is loaded (we own this code, so no need to monkey patch it with.send
).ActiveRecord
as part ofDescendantLoader
, which allows the.setup
method to function.lib/manageiq.rb
instead of Rails functions, allowing other instance methods to function.This is part of allowing
Vmdb::Settings
to be loaded without Rails, sinceVmdb::Plugins
makes use ofDescendantLoader
.Verbose description
aka: "Read this section if you are not into the whole
tl; dr;
thing"Say you had a metrics collector for
VMWare
that was mostly a pure ruby script (this is a "completely original theoretical idea" that I came with on my own... ), and really didn't need much of Rails beyond the few models it needed to put in to the database. The active record code might not even be entirely necessary if we change the queuing system.That said, the
Vmdb::Settings
code would still be most likely be necessary for this process (and/or container), and others like it, for it to boot up and be configurable via the main ManageIQ application. Thelib/vmdb/settings.rb
file, while by default won't useVmdb::Plugins
(whereDescendantLoader
is used directly), but far down the stack ofVmdb::Settings::init
, it does call out toVmdb::Plugins
(and eventuallyDescendantLoader
):https://github.com/ManageIQ/manageiq/blob/cd17a20/lib/vmdb/settings.rb#L18
https://github.com/ManageIQ/manageiq/blob/cd17a20/lib/vmdb/settings.rb#L65
https://github.com/ManageIQ/manageiq/blob/cd17a20/lib/vmdb/settings.rb#L85
https://github.com/ManageIQ/manageiq/blob/cd17a20/lib/vmdb/settings.rb#L130
https://github.com/ManageIQ/manageiq/blob/cd17a20/lib/vmdb/settings.rb#L114
Above being the lines numbers from an approximation of the callstack starting from the line of
Vmdb::Settings.init
down to the line inVmdb::Settings#template_roots
that callsVmdb::Plugins
.Explanation of End Goal and why QA steps is so minimal
End goal for this would be to be able to allow the following to work:
$ bundle exec ruby -Ilib -e "require 'vmdb/settings'; Vmdb::Settings.init"
But has a bunch of other pre-requisites that aren't handled in this PR:
MoreCoreExtensions::Shared::Nested
to allowlib/patches/config_patches.rb
to be loaded properlyRails
being loadedrequire 'lib/manageiq'
and change all instances ofRails.root
andRails.env
toManageIQ.root
andManageIQ.env
respectively (see Adds MiqHelper #15020 for some background)require
ofactive_record
and autoloadActiveRecord::Base
soconfig
works properly andrequire_dependency
is defined.vmdb/logging
in some fashion (currently used inVmdb::Plugins
, but assumes autoloading is setup)The other option to simplify some of those steps above would be to implement our own autoloading rule set, similar to what I did/described here:
#15174 (comment)
But again, something that is out of scope for this PR. Doing the end goal would be a lengthy process of multiple PRs, and this is a small component of that.
Misc Historical Context
A few PRs were merged prior to this one (one significantly so) that made the changes here necessary:
The first was needed when we switched to a provider plugins in separate repos architecture, and the second just makes sense to avoid devs having to restart their application/console session when changing code (which is slow). Both clearly wouldn't have tried to account for this case when those PR's were conceived, but now attribute to why this PR was necessary to solve the
require "vmdb/settings"
issue.Mostly included this section because I discussed (parts of) this with @Fryguy at some point, and he was un-aware of some of the changes above. Also, I didn't include this originally since I figured most people would not care for the full explanation in the steps for testing this changes "works".
Links
Steps for Testing/QA [Optional]
Run the following from the root of the ManageIQ directory:
$ bundle exec ruby -Ilib -e "require 'extensions/descendant_loader'; puts DescendantLoader.descendants_paths"
Test with both this branch and master.