Search code examples
rubyeventmachinethin

EventMachine UNIX socket connections: how do I use them with Thin running as a service?


How can I use EventMachine.connect_unix_domain while running Thin as a service (using the init script (excerpt) and configuration below). The code directly below is the problem (I get an eventmachine not initialized: evma_connect_to_unix_server error). The second code example works, but doesn't allow me to daemonize thin (I don't think). Does Thin not already have a running instance of EventMachine?

UPDATE: Oddly enough: stopping the server (with service thin stop), seems to get into the config.ru file and run the app (so it works, until the stop command times out and kills the process). What happens when thin stops that could be causing this behavior?

Problematic Code

class Server < Sinatra::Base
# Webserver code removed
end

module Handler
  def receive_data data
    $received_data_changed = 1
    $received_data = data
  end
end

$sock = EventMachine.connect_unix_domain("/tmp/mysock.sock", Handler)

Working Code

EventMachine.run do
  class Server < Sinatra::Base
  # Webserver code removed
  end

  module Handler
    def receive_data data
      $received_data_changed = 1
      $received_data = data
    end
  end
  $sock = EventMachine.connect_unix_domain("/tmp/mysock.sock", Handler)
  Server.run!(:port => 4567)
end

Init Script excerpt

DAEMON=/usr/local/bin/thin
SCRIPT_NAME=/etc/init.d/thin
CONFIG_PATH=/etc/thin

# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0

case "$1" in
  start)
    $DAEMON start --all $CONFIG_PATH
    ;;

Thin Config

--- 
chdir: /var/www
environment: development
timeout: 30
log: log/thin.log
pid: tmp/pids/thin.pid
max_conns: 1024
max_persistent_conns: 512
require: []

wait: 30
servers: 1
socket: /tmp/thin.server.sock
daemonize: true

Solution

  • What I ended up doing was removing the EventMachine.run do ... end and simply enclosing the socket connection in an EM.next_tick{ $sock = EventMachine.connect_unix_domain("/tmp/mysock.sock", Handler) }.

    Could swear I tried this once before... but it works now.

    EDIT: Idea for next_tick came from here.