Как определить, запущен ли Rails из CLI, консоли или как сервер?
У меня есть промежуточное ПО для объявления моего приложения в приложении локальной сети с использованием Bonjour, но оно также объявляет сервис, когда Rails вызывается из rake или через консоль.
Я хотел бы исключить эти случаи и использовать промежуточное программное обеспечение Bonjour, только когда Rails работает как сервер.
Конфигурация промежуточного программного обеспечения принимает процедуру исключения промежуточного программного обеспечения при определенных условиях с использованием proc
:
config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env|
env['HTTPS'] != 'on'
}
Но как мне определить, был ли Rails вызван из CLI, консоли или как сервер?
8 ответов
Подглядывать за Rails
Модуль, использующий pry, показывает, что вызовы консоли могут быть обнаружены следующим образом:
Rails.const_defined? 'Console'
И серверные вызовы как это:
Rails.const_defined? 'Server'
Краткое описание среды для каждой команды.
Я обнаружил, что существующие ответы являются неполными, избыточными или не исчерпывающими. Итак, вот формат таблицы каждой команды и как выглядит итоговая среда.
Rails 4.2
| Command | Rails.const_defined?( "Console" ) | Rails.const_defined?( "Server" ) | ARGV |
|------------------------------------|-------------------------------------|------------------------------------|---------------------------------|
| `rake db:migrate:status` | false | true | ["db:migrate:status"] |
| `rails console` | true | true | [] |
| `rails server` | false | true | [] |
| `rails g migration new_migration` | false | true | ["migration", "new_migration"] |
| `rails r "puts 'Hi'"` | false | true | [] |
Вы можете видеть, что просто проверка "Сервер" определяется как Rails
константа не будет ловить генераторы, вроде rails g migration
, Вам нужно проверить ARGV
сделать это.
Надеюсь, это поможет. У меня был только непосредственный доступ к Rails 4.2, но я могу свободно добавлять разделы для других версий Rails, а также добавлять любые дополнительные команды, которые нужно "перехватить".
Супер полезно. Спасибо @crishoj.
Я хотел исследовать объект консоли более подробно на предмет другой проблемы, над которой я работаю, и обнаружил, что константа консоли может быть достигнута с помощью Rails::Console
, так что другой вариант для проверки будет использовать:
defined? Rails::Console
defined? Rails::Server
Используя Rails 5 с или без сервера приложений, такого как Puma/Passenger, вот три способа определить, как работает ваше приложение:
# We are running in a CLI console
defined?(Rails::Console)
# We are running as a Rack application (including Rails)
caller.any?{|l| l =~ %r{/config.ru/}}
# We are running as a CLI console
caller.any?{|l| l =~ %r{/lib/rake/task.rb:\d+:in `execute'}}
"Сервер" не определен, когда Rails 5 работает под Passenger.
Лучшее решение, которое я нашел, - вариант этого ответа:
if %w(rails rake).include?(File.basename($0))
<console or runner>
else
<server>
end
В нашем проекте я должен был определить режим консоли в boot.rb, для этого я использовал:
in_console = (ARGV & ['c', 'console']).any?
Не надежное решение, но достаточно хорошее для нашего варианта использования.
Вот моя версия, которая обнаруживает sidekiq или работающий сервер на пассажирском /puma. Учитывая предыдущие ответы, он не уверен на 100%, что он будет работать во всех случаях (я не тестировал, как это происходит при запуске rails runner или задачи rake в целом)
@running_app = begin
if defined?(Rails::Console)
'Console'
elsif Sidekiq.server?
'Worker'
elsif defined?(::PhusionPassenger) || defined?(Rails::Server)
'Server'
else
nil # unknown
end
end
Для Падрино:
Консольная проверка:
if Padrino::constants.include? :Cli
#your code
end
Проверка сервера:
if !Padrino::constants.include? :Cli
#your code
end