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
Introduce bundler groups #15459
Introduce bundler groups #15459
Conversation
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, just a few minor things I noticed since seeing this last. So I guess this whole effort only took you like... say... a couple hours to put together, right?
config/application.rb
Outdated
Bundler.require(*Rails.groups, :ui_dependencies) | ||
groups = ENV['BUNDLER_GROUPS'].split(",").collect(&:to_sym) | ||
puts "loading: #{Rails.groups.inspect}" | ||
puts "loading: #{groups.inspect}" |
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.
You should remove these.
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 like them. Maybe I can disable them by default and put a bundler group nerd flag to enable them.
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 support the concept of "Nerd Flags" with this. Seems like only a few people would actually be interested in this info (I would probably fall in that category at some point ).
@@ -17,6 +17,7 @@ def do_before_work_loop | |||
|
|||
module ClassMethods | |||
def start_worker(*args) | |||
$log.info("#{self.name} $LOADED_FEATURES: #{$LOADED_FEATURES.length}") |
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.
Do we want to keep 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.
More nerd flags here. I guess it can go
app/models/miq_worker/runner.rb
Outdated
@@ -20,6 +20,7 @@ class TemporaryFailure < RuntimeError | |||
SAFE_SLEEP_SECONDS = 60 | |||
|
|||
def self.start_worker(*args) | |||
$log.info("#{self.name} $LOADED_FEATURES: #{$LOADED_FEATURES.length}") |
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.
Do we want to keep 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.
Same as above... 🤓
@@ -370,7 +370,7 @@ def self.runner_script | |||
end | |||
|
|||
def start_runner_via_spawn | |||
pid = Kernel.spawn(self.class.build_command_line(guid), :out => "/dev/null", :err => [Rails.root.join("log", "evm.log"), "a"]) | |||
pid = Kernel.spawn(self.class.build_command_line(guid), [:out, :err] => [Rails.root.join("log", "evm.log"), "a"]) |
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.
Huh... was this always like this? Oh well, 👍
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.
It was until I tried to puts above ... 😉
"MiqVimBrokerWorker" => [:manageiq_default], | ||
"MiqWebServiceWorker" => %i(rest_api ui_dependencies web_server), | ||
"MiqWebsocketWorker" => %i(ui_dependencies web_server web_socket) | ||
}.freeze |
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.
Ruh-roh... someone went "full @bdunne " on sortingthat array...
On a slightly more serious note, should we just always use %i()
for these, just to be consistent?
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.
haha, yeah... In order to mass rename some of the "conservative by default: manageiq_default" to more aggressive values... I had to sort workers by name, sort groups by name... Clearly, @bdunne would be proud.
Yeah, I can make even the single element arrays %i
if that's helpful.
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, I can make even the single element arrays %i if that's helpful.
Whatever you think makes sense. I think swapping between the two makes it a bit noisy to look at, but it is a pedantic concern. It's not like I am @bdunne ... #sickBurn #atTenThirtyAtNight #goToBedNick
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 approve of the sorting and agree with being consistent. (Although I prefer []
over %i()
)
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.
Ok, I made the decision to not make changes... We can always change this if there are compelling reasons later. I like the lack of commas and feel that %i(...)
is not required for a single element arrays.
I'm on the fence on this so do speak up if your OCD radar wants it one way or the other.
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.
@jrafanie Well, at least fix your rubocop
errors for the values being mis-aligned
@NickLaMuro did you like my 📖 in the PR description? 😉 |
It was a very cute "short story" you put together (though, I feel like I have seen the contents in some kind of "markdown-based-vim-like-presentation" or something...). I eagerly await your future releases/novels/epics. |
Gemfile
Outdated
gem "responders", "~>2.0" | ||
gem "ruby-dbus" # For external auth | ||
gem "thin", "~>1.7.0", :require => false | ||
gem "secure_headers", "~>3.0.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.
This should be above thin
|
||
### shared dependencies | ||
group :google, :openshift, :manageiq_default do | ||
gem "sshkey", "~>1.8.0", :require => false |
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.
Should this be moved to the provider gems instead? Does it need to be listed in the :google
group here since I only see app/models/container_deployment.rb:239: require 'sshkey'
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, for reference, the goal was to create groups and move dependencies into the groups to make it obvious where things belong. The next step is to push these dependencies to the correct place. Putting these in groups makes this very obvious.
end | ||
|
||
group :automate, :cockpit, :manageiq_default do | ||
gem "open4", "~>1.3.0", :require => false |
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.
Same concern here
"MiqVimBrokerWorker" => [:manageiq_default], | ||
"MiqWebServiceWorker" => %i(rest_api ui_dependencies web_server), | ||
"MiqWebsocketWorker" => %i(ui_dependencies web_server web_socket) | ||
}.freeze |
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 approve of the sorting and agree with being consistent. (Although I prefer []
over %i()
)
Use an environment variable for now to default which groups are loaded. In workers, override this variable with what individual workers need. Delay requires or move them to where they are needed. Please enter the commit message for your changes. Lines starting
Defines a variable for defining the default bundler groups in the lib/workers/miq_worker_types.rb file that is reusable.
Converts MIQ_WORKER_TYPES into a hash to then be usable to set the bundler groups for a particular worker. Also allows the run_single_worker script function with the changes to the MiqWorker and MiqWorker::Runner classes to work with the new worker spawning workflow. Using this method removes duplicate code in the lib/workers/bin directory and makes things simpler to extend in the future.
This manageiq_default group functions like the :default group that all ungrouped gems are put in. We require this new group for all processes by default and specifici worker processes can bypass it via the BUNDLER_GROUPS env variable or updating the list of groups in the worker class list.
1904ad0
to
2c295b4
Compare
gem "simple-rss", "~>1.3.1", :require => false | ||
gem "snmp", "~>1.2.0", :require => false | ||
gem "sshkey", "~>1.8.0", :require => false | ||
gem "thin", "~>1.7.0", :require => false |
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.
Very important: thin is completely gone since it doesn't support our async notifications using websockets.
2c295b4
to
fa71aa5
Compare
Ok, I think I addressed all the things. Throw more 🍅 . Is everyone ok with being aggressive in minimizing dependencies in workers and fixing any bugs that come out from that? We can always change specific workers to |
Looks good!
👍 I'm guessing from the split you do that multiple groups can be set on the command line by comma-delimiting them? |
Yes, because by default, we will be using the default anyway, so we will only see this when using |
Yes, |
Ok, @bdunne I think all the feedback has been addressed. I pushed a minor fix I found while doing the follow up to this PR... The fix ensures we check for the ui classic engine constant since that is what would setup the autoload paths. |
Some comments on commits jrafanie/manageiq@fdc3b4c~...dc40ab2 config/application.rb
lib/workers/bin/run_single_worker.rb
|
Checked commits jrafanie/manageiq@fdc3b4c~...dc40ab2 with ruby 2.2.6, rubocop 0.47.1, and haml-lint 0.20.0 config/application.rb
|
manageiq_plugin "manageiq-providers-amazon" | ||
end | ||
|
||
group :ansible, :manageiq_default 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.
Minor, but does this group mean ansible_tower, embedded_ansible or both? If the latter, why not just have two group names. Having it as ansible
-only feels confusing
group, :ansible_tower, :embedded_ansible, :manageiq_default 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.
From a high level, it's an ansible feature, to talk to ansible. Most of the providers give a way to talk to the provider and this is the same. So, it's both.
|
||
group :foreman, :manageiq_default do | ||
manageiq_plugin "manageiq-providers-foreman" | ||
gem "foreman_api_client", ">=0.1.0", :require => false, :git => "https://github.com/ManageIQ/foreman_api_client.git", :branch => "master" |
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.
Don't we own this gem? We should just cut a release.
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.
On this note, we used to have the savon gem somewhere for automate model purposes. However, I can't find it anymore. If we still need to provide it I think that it should now live in either manageiq-content
's gemspec, or even better in manageiq-appliance
's gem listing.
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.
Sure... that's outside the scope of this PR. I'm not sure why we're riding master here. Lots of the "bundler groups" have these developer friendly things that hopefully are easier to see with bundler groups. We can fix them one by one.
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 that it's outside the PR scope...just wanted to get the comment out there :)
gem "sshkey", "~>1.8.0", :require => false | ||
end | ||
|
||
group :automate, :cockpit, :manageiq_default 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.
Does automate here mean automation_engine or the automate model (i.e. manageiq-content)?
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.
We can rename to automate_engine if you want... I tried to line these up with basic features than to try to be very specific.
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 tried to line these up with basic features than to try to be very specific.
I'm concerned that this will actually make things more confusing (as exemplified here and with the ansible comment above) (NOTE: not pushing my agenda...feel free to say "maybe later" 😉 )
|
||
### end of provider bundler groups | ||
|
||
group :automate, :seed, :manageiq_default 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.
I think the :automate
group should be named :automation_engine
to distinguish it from the automate model.
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.
Ok
@@ -24,9 +24,6 @@ def preload_for_console | |||
end | |||
|
|||
def preload_for_worker_role | |||
# Make these constants globally available | |||
::UiConstants | |||
|
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.
@jrafanie looks like this is still needed.....
17:04:06 bdunne@bdunne-t460p:~/projects/redhat/manageiq (unclaimed_deletions)$ rails s
=> Booting Puma
=> Rails 5.0.4 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
** ManageIQ master; Database: adapter=postgresql, name=vmdb_development, host=
** Using session_store: ActionDispatch::Session::MemCacheStore
I, [2017-07-05T17:07:40.017774 #3074] INFO -- : Initializing websocket worker!
Puma starting in single mode...
* Version 3.3.0 (ruby 2.3.3-p222), codename: Jovial Platypus
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
W, [2017-07-05T17:07:49.288776 #3074] WARN -- : DEPRECATION WARNING: You didn't set `secret_key_base`. Read the upgrade documentation to learn more about this new config option. (called from env_config at /home/bdunne/.gem/ruby/2.3.3/gems/railties-5.0.4/lib/rails/application.rb:246)
I, [2017-07-05T17:07:49.289844 #3074] INFO -- : Started GET "/" for ::1 at 2017-07-05 17:07:49 -0400
I, [2017-07-05T17:07:51.393252 #3074] INFO -- : Processing by DashboardController#login as HTML
F, [2017-07-05T17:07:51.649379 #3074] FATAL -- : Error caught: [NameError] uninitialized constant ApplicationController::PPCHOICES
/home/bdunne/.gem/ruby/2.3.3/bundler/gems/manageiq-ui-classic-937e70b2d07b/app/controllers/application_controller.rb:1874:in `get_global_session_data'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:382:in `block in make_lambda'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:150:in `block (2 levels) in halting_and_conditional'
/home/bdunne/.gem/ruby/2.3.3/gems/actionpack-5.0.4/lib/abstract_controller/callbacks.rb:12:in `block (2 levels) in <module:Callbacks>'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:151:in `block in halting_and_conditional'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:454:in `block in call'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:454:in `each'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:454:in `call'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:101:in `__run_callbacks__'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:750:in `_run_process_action_callbacks'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/callbacks.rb:90:in `run_callbacks'
/home/bdunne/.gem/ruby/2.3.3/gems/actionpack-5.0.4/lib/abstract_controller/callbacks.rb:19:in `process_action'
/home/bdunne/.gem/ruby/2.3.3/gems/actionpack-5.0.4/lib/action_controller/metal/rescue.rb:20:in `process_action'
/home/bdunne/.gem/ruby/2.3.3/gems/actionpack-5.0.4/lib/action_controller/metal/instrumentation.rb:32:in `block in process_action'
/home/bdunne/.gem/ruby/2.3.3/gems/activesupport-5.0.4/lib/active_support/notifications.rb:164:in `block in instrument'
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.
Reverted by #15518
if defined?(Bundler) | ||
Bundler.require(*Rails.groups, :ui_dependencies) | ||
groups = ENV['BUNDLER_GROUPS'].split(",").collect(&:to_sym) |
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.
You might want to tack in a .map(&:strip)
, just in case someone does a comma separated list and instinctively adds in commas
BUNDLER_GROUPS="rest_api, ui_dependencies"
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.
Hmm, are you saying they'd put spaces after each comma?
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...it's possible...I do it all the time, instinctively.
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.
Super proud of @Fryguy for not using collect
here
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.
Believe it or not, I actually prefer map
😄
You want to explicitly disable the rubocop for Rails/Output since these are intentional. |
This file pollutes the global namespace for legacy bad reasons. Followup to bundler groups PR: ManageIQ/manageiq#15459 The autoloading of ui constants in manageiq was reverted back here: ManageIQ/manageiq#15518
See: ManageIQ/manageiq-ui-classic#1658 Followup to bundler groups PR: ManageIQ#15459 The autoloading of ui constants in manageiq was reverted back here: ManageIQ#15518
What is a bundler group?
OR:
Gem with no group are put in the :default bundler group.
How are they used?
Bundler.require(*Rails.groups)
What this does:
default bundler group + the Rails.env group: (test, development, or production)
Why?
We need to isolate dependencies but splitting them all out is hard as some are shared dependencies and the "core" manageiq features (models, basic libs) is not in a gemspec file that each worker could include in a
Gemfile
.First step solution, use bundler groups to group dependencies and requires
The idea: "tag" our gems with a "specific feature" AND a manageiq_default group:
How?
config/application.rb can now do:
So, you can inject your dependencies at command line and for each process type by injecting them into an environment variable.
Workers specify their dependencies OR you can do BUNDLER_GROUPS="rest_api" bin/rails server
Is this the long term solution?
No. The proper way to do this is to move all dependencies where they belong and have a
Gemfile
for each process type. But, that's HARD and risky.Bundler groups are safer and can be done simultaneously for
4.6gaprindashvili and a bit more aggressively for master/5.0h-release. EDIT @FryguySummary:
Loading all dependencies via the manageiq_default bundle group:
With none of the manageiq_default gems:
Not all workers will exclude all of the manageiq_default gems but it can pick and choose which ones it needs.