Remus Rusanu
Remus Rusanu

Reputation: 294237

Detect if application was started as HTTP server or not (rake task, rconsole etc)

I'm using EventMachine and Monetarily to start e TCP server along with my rails application. This is started from config/initializers/momentarily.rb.

My problem is that it starts also when I run rake tasks, like db:migrate. I only want it to start when when I start the HTTP server. Environments won't help, since both the server start and rake tasks are under Development environment. Is there a way of knowing that the application is running the HTTP server as opposed to anything else? Note that is not only rake tasks, the EM starts also if I run the rails console, which is again something not desirable for my case.

Upvotes: 12

Views: 3081

Answers (7)

pokrovskyy
pokrovskyy

Reputation: 487

In addition to a great answer by Frederick Cheung above, there can be some other "footprints" in actual process environment. Eg. Phusion Passenger adds certain variables to ENV such as:

PASSENGER_APP_ENV
IN_PASSENGER
PASSENGER_SPAWN_WORK_DIR
PASSENGER_USE_FEEDBACK_FD

Web servers typically can also set SERVER_SOFTWARE variable eg.:

SERVER_SOFTWARE=nginx/1.15.8 Phusion_Passenger/6.0.2

Upvotes: 0

Vishal
Vishal

Reputation: 2181

Set an environment variable in config.ru file, and use it anywhere in the code to detect if it's executed using a rails server command only.

For e.g.

  • File: config.ru

    ENV['server_mode'] = '1'
    

And using it somewhere as:

  • File: config/environment.rb

    Thread.new { infinite_loop! }.join if ENV['server_mode'] = '1'
    

Reference: Answer

Upvotes: 7

Frederick Cheung
Frederick Cheung

Reputation: 84114

There's not a great way of doing this that I know of. You could copy newrelic's approach (check discover_dispatcher in local_environment.rb) which basically has a list of heuristics used to detect if it is running inside passenger, thin, etc.

For passenger it checks

defined?(::PhusionPassenger)

for thin it checks

if defined?(::Thin) && defined?(::Thin::Server)

Upvotes: 8

Tema Bolshakov
Tema Bolshakov

Reputation: 1193

unless File.basename($0) == "rake" && ARGV.include?("db:migrate")
  # you are not in rake db:migrate
end

Upvotes: 9

Gordon Wilson
Gordon Wilson

Reputation: 26384

After your application launches, you could have it shell out to check ps. If ps shows that the HTTP server is running and the running HTTP server has the same pid as your application (check the pid by inspecting $$), then you could launch the TCP server.

Upvotes: 0

Stefan
Stefan

Reputation: 114158

Don't start that other server from an initializer. Create a daemon in script/momentarily and start it from within your app.

Upvotes: 0

severin
severin

Reputation: 10268

Maybe you can implement a switch in the initializer based on ARGV?

Something like:

if ARGV.join(' ').match /something/
  # your initializer code here
end

Upvotes: 0

Related Questions