-
-
Notifications
You must be signed in to change notification settings - Fork 280
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
Initialize Rails before parsing Config File #686
Conversation
Hey @csebryam, thanks for opening this PR and sorry I've been slow to give feedback. In general, I'm open to this kind of change, but I'm hesitant because I think it might be backwards-incompatible. In some of the applications I maintain, we reference, for example, the Shoryuken logger instance in a Rails initializer like so Rails.logger = Shoryuken::Logging.logger I think this change might actually not break my applications in this case, but it's difficult to say that this change won't break anyone's current configuration. What would help me as a maintainer would be to know a little bit more about your use case. What are you trying to accomplish with this change? Do you expect to have to export environment variables, for example, in a Rails initializer, in order to read them from If so, one workaround is to use Shoryuken's configuration API instead of the YAML file. An example is in https://github.com/ruby-shoryuken/shoryuken/wiki/Rails-Integration-Active-Job # config/initializers/shoryuken.rb
Shoryuken.configure_server do |config|
# Replace Rails logger so messages are logged wherever Shoryuken is logging
# Note: this entire block is only run by the processor, so we don't overwrite
# the logger when the app is running as usual.
Rails.logger = Shoryuken::Logging.logger
Rails.logger.level = Rails.application.config.log_level
# config.server_middleware do |chain|
# chain.add Shoryuken::MyMiddleware
# end
# For dynamically adding queues prefixed by Rails.env
# Shoryuken.add_group('default', 25)
# %w(queue1 queue2).each do |name|
# Shoryuken.add_queue("#{Rails.env}_#{name}", 1, 'default')
# end
end |
@cjlarose Thanks for your response and for being open to adding these changes. Also, thanks for sharing your To avoid any logger issues, we could move the def setup_options
initialize_logger
initialize_rails if load_rails?
initialize_options
end Use case:
In the Hope to hear your thoughts. |
Ok this definitely feels like the right change to make, though it does seem like it'd warrant major version bump. I don't think it's necessary to move the I just want to clarify what the expected behavior is in a bunch of cases so that we can clearly communicate this change in the changelog. If a user, for example, was using |
@cjlarose Sorry for my delay in responding, this took some digging. Bumping to a major version makes sense to me that way it doesn't break anyones expected behavior.
After some investigation, this PR does change the order things get interpreted. The order things get loaded in this PR:
loader = EnvironmentLoader.setup_options(options)
loader.load Code snippet (A) def add_group(group, concurrency = nil, delay: nil)
concurrency ||= options[:concurrency]
delay ||= options[:delay]
...
end Again, keeping any defaults configured in the initializer. Previous Version BelowWhats more, loading rails before or after doesn't change much in terms of how defaults get interpreted. def load
load_rails
prefix_active_job_queue_names
parse_queues
...
end This is because in both cases rails gets loaded/initialized before In your example above: Shoryuken.configure_server do |config|
Shoryuken.add_group('default', 25)
%w(queue1 queue2).each do |name|
Shoryuken.add_queue("#{Rails.env}_#{name}", 1, 'default')
end
end This code is essentially what |
@cjlarose Not sure if I was able to answer your questions fully but I'm happy to look into anything else. Do you think this PR is ready to merge? |
Hey @csebryam! I appreciate you figuring out the details on how everything gets initialized. Sorry I haven't been responsive--I took some vacation time. This is still on my radar, though. I'll take a deeper look at it and get you some feedback! |
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.
Hey @csebryam ! Sorry it took so long to get you some feedback. I was able to take a deeper look and left some comments, but this change looks overall pretty great! Thanks again for taking this on.
@@ -18,12 +18,12 @@ def initialize(options) | |||
end | |||
|
|||
def setup_options | |||
initialize_rails if load_rails? | |||
initialize_options |
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.
Since EnvironmentLoader#intialize_options
will read in the config file first, then the CLI args, it seems like we can safely remove the call to merge in the CLI args from Shoryuken::Runner#run
. What do you think?
shoryuken/lib/shoryuken/runner.rb
Lines 33 to 34 in b0dc0c5
# When cli args exist, override options in config file | |
Shoryuken.options.merge!(options) |
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.
That makes sense. Also, removing this line will clear things up as to when/how the options get loaded and avoids further confusion.
lib/shoryuken/environment_loader.rb
Outdated
@@ -79,6 +79,10 @@ def load_rails | |||
end | |||
end | |||
|
|||
def load_rails? | |||
options[:rails] || Shoryuken.options[:rails] |
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.
Is it possible to rely solely on the CLI arg options[:rails]
here? It's not clear to me in what situation options[:rails]
would be falsey here, but Shoryuken.options[:rails]
would be truthy here, especially since by the time this method is invoked, initialize_options
has not yet run.
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 would be ok with just having options[:rails]
, that is how I'm using it. Though, I wanted to keep the existing functionality in case someone was enabling it through the config/shoryuken.yml
file.
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.
Correct me if I'm wrong, but Shoryuken.options[:rails]
won't be populated by the value in config/shoryuken.yml
until initialize_options
runs. So if the intent is to preserve functionality of setting rails: true
in the config file, I don't think this code accomplishes that.
Either way, I don't think it's necessary to preserve the behavior of allowing rails: true
to be set in the config file because it's a bit circular: if we have to read the config file to know whether or not to load rails, but we also don't want to read the config file until after initializing Rails, that seems messy.
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.
That's right, by the time initialize_options
runs, it has already passed the option to initialize_rails
.
if we have to read the config file to know whether or not to load rails, but we also don't want to read the config file until after initializing Rails, that seems messy.
That is a very good point!
Moving forward with this change to only allowing CLI arg to load rails.
This is being removed since `Runner::EnvironmentLoader.setup_options(options)` will read from the CLI options to load rails subsequently loading the any config file options. Therefore, overriding with CLI options is no longer needed.
Changes look perfect. I'll have to take another pass later and do some testing on some of my own applications, but I think this is just about good to go. |
Tested on my own applications. Looks great! Thanks so much for this! |
I just wanted to say a belated thank you for this change, it helped to dry up our app's config nicely 🙏 |
Part 1
Description
When you specify to load rails in the
shoryuken.yml
file ( i.erails: true
),Shoryuken::EnvironmentLoader#setup_options
will read theconfig_file
before rails has had a chance to be initialized. Any declared rails environment variables will not be present at this time.In the example below:
AWS_SQS_QUEUE
will not be present in the rails environment variables as it is currently. As a result a log output will show this message:WARN: No queues supplied
Fixes:
Initialize rails as the first step in the
#setup_options
Part 2
Description
Currently if you set the
:rails
flag in the CLI with the-R
option, theShoryuken::Runner
will override options in the config files with the CLI optionsWhen
loader.load
gets called, we run into the same issue as Part 1. Theconfig_file
has already been read-in and any rails environment variables were not present at that time. Again, this is because loading rails happens too late in the process, in the#load
method.Fixes
Shoryuken::EnvironmentLoader
will initialize rails looking for flags from eitherShoryuken.options
or CLIoptions
hash. Seeload_rails?
method.Other
Fixes issues similar to these #670
Similar Issues #511