2013-05-19 3 views
0

У меня есть Rails 3.2 приложение работает на тонком сервере и в application.rb Я хочу начать EventMachine:Запуск EventMachine в новой нити после Rails загружается с помощью тонких

# application.rb 

config.after_initialize do 
    if ENV['EM'] 
    EM.run do 
     host = '0.0.0.0' 
     port = 3001 

     # hit Ctrl + C to stop 
     Signal.trap("INT") { EventMachine.stop } 
     Signal.trap("TERM") { EventMachine.stop } 

     EventMachine::start_server host, port, SomeModule 

     puts "EventMachine running on #{host}:#{port}. Ctrl + C to stop." 
    end 
    end 
end 

SomeModule имеет код, который зависит от Rails загружается. Вот почему я помещал это в блок after_initialize вместо инициализатора.

Теперь, когда я начинаю свой сервер (с rails s) мой вывод выглядит отлично:

=> Booting Thin 
=> Rails 3.2.13 application starting in development on http://0.0.0.0:3000 
=> Call with -d to detach 
=> Ctrl-C to shutdown server 
EventMachine running on 0.0.0.0:3001. Ctrl + C to stop. 

Но когда я иду на локальный в моем браузере я получаю 204 No Content ответ.

Я могу думать о нескольких вещах, которые вызывают это, но не решение :)

  • Может быть, я начинаю с EventMachine на том же потоке, блокируя приложение Rails. Но Тин должен справиться с этим?
  • Может быть, я должен начать свой сервер по-другому, но как тогда?

ответ

3

После еще нескольких поисковых запросов я обнаружил, что, поскольку я использую Thin, мне не нужно запускать еще один EventMachine.

Мой after_initialize блок теперь выглядит следующим образом:

config.after_initialize do 
    include SomeModule 
end 

И в SomeModule я обернул свой код в EM.next_tick блоке или я получаю «eventmachine не инициализирован: evma_connect_to_server (RuntimeError)» ошибки.

Использование EventMachine в приложение Rails с Thin было намного легче, чем я думал :)

+0

Дополнительная информация о [EventMachine github wiki] (https://github.com/eventmachine/eventmachine/wiki/FAQ#does-em-work-with-other-ruby-threads-ru) – thinkOfaNumber

0

Вы должны предотвратить автозагрузку своего рубинового кода, который вызывает EventMachine, иначе он заблокирует ваш основной поток. Поместите свой скрипт в lib/daemons, затем создайте сценарий запуска для своего EventMachine и используйте его как демон. I.e .:

#!/usr/bin/env ruby 
# this is: ./scripts/my_daemon 

require 'daemons' 

options = { 
    multiple: false, 
    backtrace: true, 
    app_name: 'my_daemon', 
    dir_mode: :normal, 
    dir: '/tmp/my_daemon', 
    log_dir: '/tmp/my_daemon', 
    log_output: true, 
    ARGV: ARGV, 
} 

system "mkdir -p /tmp/my_daemons" 
Daemons.run(File.join(File.dirname(__FILE__), '../lib/daemons/my_daemon.rb'), options) 

Вам необходимо добавить драгоценный камень «демонов» в ваш Gemfile.

Затем просто запустите script/my_daemon start из рельсов root. Есть несколько команд:

  • скрипта/my_daemon остановка # останавливает демон
  • скрипт/my_daemon запустить # пробеги на переднем плане, так что вы можете увидеть результат и отлаживать его
  • скрипта/my_daemon статус # показывает, если что-нибудь работает

Вы найдете журналы в /tmp/my_daemons/my_daemon.output

Узнайте больше о демонах здесь: http://daemons.rubyforge.org/Daemons.html

+0

В то же время я нашел решение. Нужен ли мне демон, если я использую Thin? – Flauwekeul

+0

Это зависит от того, какую проблему вы решаете. Драгоценный камень Daemons дает вам больше контроля над вашими фоновыми процессами, он отделяет EventMachine от вашего основного приложения, вы сможете его запустить или остановить самостоятельно. И вы можете включить config/environment.rb, чтобы получить полный доступ к вашему Rails-приложению в вашем демоне. Но поскольку вы нашли более простое решение, оно может сработать для вас. :) – Spajus

+0

Это звучит как-то, что мне может понадобиться в будущем, и я обязательно изучу его. Благодаря! – Flauwekeul