No middleware without touching RACK_ENV

Lin Jen-Shin (godfat) godfat at godfat.org
Mon Jan 28 14:43:39 UTC 2013


On Sat, Jan 26, 2013 at 2:39 AM, Eric Wong <normalperson at yhbt.net> wrote:
> Doesn't Rails favor RAILS_ENV over RACK_ENV?  unicorn ignores RAILS_ENV
> (unicorn_rails respects RAILS_ENV, but unicorn_rails isn't recommended
> for modern (Rack-enabled) Rails)

Yes, it is. But it would still look into RACK_ENV if RAILS_ENV is not available.
One solution would be setting RAILS_ENV=development while setting
RACK_ENV=none. I don't really want to do this for several reasons:

* It would be better to keep RAILS_ENV == RACK_ENV to avoid confusion.
* It might be tricky to make RAILS_ENV default to development while setting
  RACK_ENV since Rails would be looking into it. So we need to make sure
  that Rails is loaded and default to development and then we can setup
  RACK_ENV to avoid messing up the original Rails default.

> Is there a benefit which RACK_ENV=development gives you for Rails
> that RAILS_ENV=development does not give you?

The main reason is that I want to avoid confusion. The other reason
is that that's also how Heroku tries to use. I think it's also because of
consistency. (so that we don't have to distinguish RACK_ENV and RAILS_ENV)

The other reason would be making them different might cause some
issues as Rails would also be looking at RACK_ENV.

> Fwiw, the times I worked on Rails, I used customized dev environments
> anyways, so I would use RAILS_ENV=dev_local or RAILS_ENV=dev_$NETWORK
> for switching between a localhost-only vs networked setup.

I would also do this I guess, but since I am not the only one working on
the application, I would avoid making such changes. We have a lot of
configurations depending on the word "development" already.

>> I know this is somehow a spec from Rack, but I guess I
>> don't like this behaviour. One workaround would be
>> providing a `after_app_load' hook, and we add this to
>> the bottom of config.ru:
>>
>>   ENV['RACK_ENV_ORIGINAL'] = ENV['RACK_ENV']
>>   ENV['RACK_ENV'] = 'none'
>>
>> and add this to the unicorn configuration file:
>>
>>   after_app_load do |_|
>>     ENV['RACK_ENV'] = ENV['RACK_ENV_ORIGINAL']
>>   end
>>
>> This is probably a stupid hack, but I wonder if after_app_load
>> hook would be useful for other cases?
>
> I don't see how this hook has benefits over putting this in config.ru
> (or somewhere else in your app, since your app is already loaded...)

It's better to me because it's clear on the loading order.
The point where to change RACK_ENV=none would be
after Rails loaded (to avoid messing Rails up), and
_before Unicorn inserting middleware_. And then I would
like to switch RACK_ENV=RAILS_ENV to avoid confusion.
It's hard to tell where I can put this code.

> I'd imagine users wanting the same app-wide settings going between
> different application servers, too.

Speaking to this, I might want to complain about the other severs :P
As far as I know, only if you use `rackup' would you get those middleware.

That is, `unicorn' is compatible with `rackup'. That's a good thing.
But it seems to me that both `thin' and `puma' (and maybe including
others, I didn't check) would not do this if you use their command line
tools. They even have different options to enable Rack::CommonLogger.

Actually this is also the reason why sometimes `thin' and `unicorn'
worked differently when people switching from Thin to Unicorn.
And you know a lot of people are using Thin in the first place,
thus sometimes blaming Unicorn works differently.

I am not sure how many people are using `rackup', but according to
my observation, not too much. If people are using Sinatra directly,
eventually they would launch the server via Rack::Handler.get.run,
which does not try to wrap additional middleware as what `rackup'
would do if I read correctly.

So I am not sure if a lot of people would be expecting this actually.
I used to use `rackup' a lot to get consistent behaviour, but it looks to
me not many people even know the existence of rackup :(

> I'm against adding more command-line or config options, especially
> around loading middleware.  RACK_ENV is already a source of confusion,
> and Rails also has/(or had?) it's own middleware loading scheme
> independent of config.ru.

Yes, I hate that, too. I can't complain about Rails less :P I don't understand
why people are building those middleware scheme on their own way,
even Sinatra does this. I guess they want more control over middleware,
so that they can reorder, delete, insert more/less middleware somehow.
I guess that makes sense in some way... but they should be really in
Rack instead of each web framework IMHO.

> git format-patch + git send-email is the recommended way if your
> mail client cannot be taught to leave formatting alone.  Also this
> is easy for sending multiple patches in the same thread.
>
> git format-patch --stdout with a good mail client which will not wrap
> messages is also great (especially for single patches).
>
> Attachments (generated using git format-patch) for text/x-diff should be
> accepted by Mailman.  Attached patches are a last resort, I prefer
> inline patches since I can quote/reply to them inline.
>
> (same patch submission guidelines as git or Linux kernel)

Last time I tried to setup SMTP for git send-email failed.
I'll try again next time. Thanks!

> Commit messages should explain why a change is made/needed, not just
> what it does.

Yeah, I know, but I can understand if none of them is acceptable,
(that's why I didn't bring this up in the first place) and the reason to
build those features might be arguing. So instead of writing them
carefully, I decided to bring this up sooner and then we can work out
the true reason later on :D

Thanks a lot for your time.


More information about the mongrel-unicorn mailing list