Search code examples
ruby-on-railseventmachinethin

Running EventMachine in new Thread after Rails is loaded using Thin


I have a Rails 3.2 app running on a Thin server and in application.rb I want to start EventMachine:

# 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 has code that depends on Rails being loaded. That's why I put this in the after_initialize block instead of in an initializer.

Now when I start my server (with rails s) my output looks fine:

=> 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.

But when I go to localhost in my browser I get a 204 No Content response.

I can think of several things that causes this, but not a solution :)

  • Maybe I'm starting the EventMachine on the same thread blocking the Rails app. But Thin should handle this right?
  • Maybe I should start my server differently, but how then?

Solution

  • After some more Googling I found that since I'm using Thin I don't need to run another EventMachine.

    My after_initialize block now looks like this:

    config.after_initialize do
      include SomeModule
    end
    

    And in SomeModule I wrapped my code in an EM.next_tick block or I'd get a "eventmachine not initialized: evma_connect_to_server (RuntimeError)" error.

    Using EventMachine in a Rails app with Thin was way easier than I thought :)