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

Implement user_supplied_options behavior. #1234

Conversation

schneems
Copy link
Contributor

@schneems schneems commented Mar 6, 2017

This is the Puma side of rails/rails#28137

When options are passed to the Puma rack handler it is unknown if the options were set via a framework as a default or via a user. Puma currently has 3 different sources of configuration, the user via command line, the config files, and defaults.

Rails 5.1+ will record the values actually specified by the user versus the values specified by the frameworks. It passes these values to the Rack handler and now it's up to Puma to do something with that information.

When only framework defaults are passed it will set

options[:user_supplied_options] = []

When one or more options are specified by the user such as :Port then those keys will be in the array. In that example it will look like this

options[:user_supplied_options] = [:Port]

This change is 100% backwards compatible. If the framework is older and does not pass this information then the user_supplied_options will not be set, in that case we assume all values are user supplied.

Internally we accomplish this separation by replacing LeveledOptions which was a generic way of specifying options with different priorities with a more explicit UserFileDefaultOptions this assumes only 3 levels of options and it will use them in the order supplied (user config wins over file based config wins over defaults).

Now instead of using 1 dsl to set all values, we use 3. A user dsl, a file dsl and a Configuration.new will return all 3 DSLs to the block. It's up to the person using the block to use the correct dsl corresponding to the source of data they are getting.

@schneems schneems force-pushed the schneems/puma-port-problem-patched-per-prior-parley-possibly branch from e3bd773 to 0e519a8 Compare March 6, 2017 18:44
@@ -4,9 +4,11 @@
begin
require "bundler/setup"
rescue LoadError
Copy link
Member

Choose a reason for hiding this comment

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

Aha, yeah, this is probably the correct fix.

@nateberkopec
Copy link
Member

@schneems is this done now?

@schneems
Copy link
Contributor Author

schneems commented Mar 7, 2017

Yes, please review. Ping me with any questions.

@@ -151,14 +143,17 @@ def initialize(options={}, &blk)
attr_reader :options, :plugins

def configure(&blk)
@options.shift
DSL.new(@options, self)._run(&blk)
blk.call(@user_dsl, @file_dsl, @default_dsl)
Copy link
Member

Choose a reason for hiding this comment

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

Can't we just yield?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure if you prefer that.

Copy link
Member

Choose a reason for hiding this comment

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

no biggie, I just have a habit of using yield

end

def test_default_port_when_no_config_file
options = {}
Copy link
Member

Choose a reason for hiding this comment

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

Just use @options?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That was a copy pasta error. Will fix


def test_config_wins_over_default
file_port = 6001
@options = {}
Copy link
Member

Choose a reason for hiding this comment

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

Already set

def test_user_port_wins_over_config
user_port = 5001
file_port = 6001
@options = {}
Copy link
Member

Choose a reason for hiding this comment

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

samesies

The RackHandler for Puma has configuration options that I want to test without booting up a server. By separating out into a new method we can do this easily.
When options are passed to the Puma rack handler it is unknown if the options were set via a framework as a default or via a user. Puma currently has 3 different sources of configuration, the user via command line, the config files, and defaults. 

Rails 5.1+ will record the values actually specified by the user versus the values specified by the frameworks. It passes these values to the Rack handler and now it's up to Puma to do something with that information.

When only framework defaults are passed it will set

```
options[:user_supplied_options] = []
```

When one or more options are specified by the user such as `:Port` then those keys will be in the array. In that example it will look like this


```
options[:user_supplied_options] = [:Port]
```

This change is 100% backwards compatible. If the framework is older and does not pass this information then the `user_supplied_options` will not be set, in that case we assume all values are user supplied.

Internally we accomplish this separation by replacing `LeveledOptions` which was a generic way of specifying options with different priorities with a more explicit `UserFileDefaultOptions` this assumes only 3 levels of options and it will use them in the order supplied (user config wins over file based config wins over defaults).

Now instead of using 1 dsl to set all values, we use 3. A user dsl, a file dsl and a Configuration.new` will return all 3 DSLs to the block. It's up to the person using the block to use the correct dsl corresponding to the source of data they are getting.
@schneems schneems force-pushed the schneems/puma-port-problem-patched-per-prior-parley-possibly branch from 4e892e7 to 852f52f Compare March 9, 2017 17:38
@schneems schneems merged commit 992fd0d into puma:master Mar 9, 2017
@allaire
Copy link
Contributor

allaire commented Jun 2, 2017

@schneems Hi Richard, I think this commit broke the correct loading of puma environment configuration file.

Before 3.8.0, I was able to run RACK_ENV=production bundle exec puma start and it was loading automatically config/puma/production.rb.

On 3.8.0, it's not picking up the production.rb config file. You can test this by simply putting a raise inside the config/puma/production.rb file.

Might be related? #1269

@schneems
Copy link
Contributor Author

schneems commented Jun 2, 2017

I'm not sure. Can you try with 3.9.0 and if it's still broken open a new issue with an example app?

@allaire
Copy link
Contributor

allaire commented Jun 2, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants