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

6

5

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)?

Veronique answered 9/11, 2011 at 1:1 Comment(0)
E
3

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)"
Eccles answered 20/12, 2011 at 17:10 Comment(0)
D
3

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

Disruptive answered 28/3, 2013 at 12:8 Comment(0)
L
1

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!

Lilley answered 8/1, 2015 at 22:27 Comment(0)
S
0

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.

Spread answered 7/12, 2011 at 6:15 Comment(0)
S
0

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

Southwick answered 28/6, 2014 at 0:21 Comment(0)
I
0

If you use unicorn_rails, below code will help

defined?(::Unicorn::Launcher)
Inquietude answered 25/8, 2022 at 9:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.