简体   繁体   中英

How to detect if a rails app is running under Unicorn?

I need to setup a connection to an external service in my Rails app. I do this in an initializer. The problem is that the service library uses threaded delivery (which I need, because I can't have it bogging down requests), but the Unicorn life cycle causes the thread to be killed and the workers never see it. One solution is to invoke a new connection on every request, but that is unnecessarily wasteful.

The optimal solution is to setup the up the connection in an after_fork block in the unicorn config. The problem there is that doesn't get invoked outside of unicorn, which means we can't test it in development/testing environments.

So the question is, what is the best way to determine whether a Rails app is running under Unicorn (either master or worker process)?

You can check for defined?(Unicorn) and in your Gemfile set: gem :unicorn, require: false In fact you don't need Unicorn library loaded in you rails application. Server is started by unicorn command from shell

There is an environment variable that is accessible in Rails (I know it exists in 3.0 and 3.1), check the value of env['SERVER_SOFTWARE'] . You could just put a regex or string compare against that value to determine what server you are running under.

I have a template in my admin that goes through the env variable and spits out its content.

Unicorn 4.0.1

env['SERVER_SOFTWARE'] => "Unicorn 4.0.1"

rails server (webrick)

env['SERVER_SOFTWARE'] => "WEBrick/1.3.1 (Ruby/1.9.3/2011-10-30)"

Checking for Unicorn constant seems a good solution, BUT it depends very much on whether require: false is provided in the Gemfile . If it isn't (which is quite probable), the check might give a false positive.

I've solved it in a very straightforward manner:

# `config/unicorn.rb` (or alike):
ENV["UNICORN"] = 1

...

# `config/environments/development.rb` (or alike):
...
# Log to stdout if Web server is Unicorn.
if ENV["UNICORN"].to_i > 0
  config.logger = Logger.new(STDOUT)
end

Cheers!

Inside config/unicorn.rb Define ENV variable as

ENV['RAILS_STDOUT_LOG']='1' worker_processes 3 timeout 90

and then this variable ENV['RAILS_STDOUT_LOG'] will be accessible anywhere in your Rails app worker thread.

my issue: I wanted to output all the logs(SQL queries) when on the Unicorn workers and not on any other workers on Heroku, so what I did is adding env variable in the unicorn configuration file

If you use unicorn_rails , below code will help

defined?(::Unicorn::Launcher)

You could check to see if the Unicorn module has been defined with Object.constants.include?('Unicorn') .

This is very specific to Unicorn, of course. A more general approach would be to have a method which sets up your connection and remembers it's already done so. If it gets called multiple times, it just returns doing nothing on subsequent calls. Then you call the method in after_fork and in a before_filter in your application controller. If it's been run in the after_fork it does nothing in the before_filter, if it hasn't been run yet it does its thing on the first request and nothing on subsequent requests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM