Class: AMQP::Utilities::EventLoopHelper

Inherits:
Object
  • Object
show all
Defined in:
lib/amqp/utilities/event_loop_helper.rb

Overview

A helper that starts EventMachine reactor the optimal way depending on what Web server (if any) you are running. It should not be considered a 100% safe, general purpose EventMachine reactor “on/off switch” but is very useful in Web applications and some stand-alone applications.

This helper was inspired by Qusion project by Dan DeLeo.

Key methods

Class Method Summary collapse

Class Method Details

.eventmachine_threadObject


23
24
25
# File 'lib/amqp/utilities/event_loop_helper.rb', line 23

def self.eventmachine_thread
  @eventmachine_thread
end

.reactor_running?Boolean

self.eventmachine_thread


27
28
29
# File 'lib/amqp/utilities/event_loop_helper.rb', line 27

def self.reactor_running?
  EventMachine.reactor_running?
end

.run(&block) ⇒ Thread

Note:

This method, unlike EventMachine.run, DOES NOT block current thread.

A helper that detects what app server (if any) is running and starts EventMachine reactor in the most optimal way. For event-driven servers like Thin and Goliath, this means relying on them starting the reactor but delaying execution of a block you pass to run until reactor is actually running.

For Unicorn, Passenger, Mongrel and other servers and standalone apps EventMachine is started in a separate thread.

Examples:

Using EventLoopHelper.run to start EventMachine reactor the optimal way without blocking current thread


AMQP::Utilities::EventLoopHelper.run do
  # Sets up default connection, accessible via AMQP.connection, and opens a channel
  # accessible via AMQP.channel for convenience
  AMQP.start

  exchange          = AMQP.channel.fanout("amq.fanout")

  AMQP.channel.queue("", :auto_delete => true, :exclusive => true).bind(exchange)
  AMQP::channel.default_exchange.publish("Started!", :routing_key => AMQP::State.queue.name)
end

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/amqp/utilities/event_loop_helper.rb', line 63

def self.run(&block)
  if reactor_running?
    EventMachine.run(&block)

    return
  end

  @eventmachine_thread  ||= begin
                              case self.server_type
                              when :thin, :goliath, :evented_mongrel then
                                EventMachine.next_tick { block.call }
                                Thread.current
                              when :unicorn, :passenger, :mongrel, :scgi, :webrick, nil then
                                t = Thread.new { EventMachine.run(&block) }
                                # give EventMachine reactor some time to start
                                sleep(0.25)

                                t
                              else
                                t = Thread.new { EventMachine.run(&block) }
                                # give EventMachine reactor some time to start
                                sleep(0.25)

                                t
                              end
                            end

  @eventmachine_thread
end

.server_typeObject

Type of server (if any) that is running.

See Also:


34
35
36
# File 'lib/amqp/utilities/event_loop_helper.rb', line 34

def self.server_type
  @server_type ||= ServerType.detect
end