EM::Connection
Backwards compatibility with 0.7.0.a25. MK.
Initiates connection to AMQP broker. If callback is given, runs it when (and if) AMQP connection succeeds.
@option settings [String] :host (“127.0.0.1“) Hostname AMQ broker runs on. @option settings [String] :port (5672) Port AMQ broker listens on. @option settings [String] :vhost (“/”) Virtual host to use. @option settings [String] :user (“guest”) Username to use for authentication. @option settings [String] :pass (“guest”) Password to use for authentication. @option settings [String] :ssl (false) Should be use TLS (SSL) for connection? @option settings [String] :timeout (nil) Connection timeout. @option settings [String] :logging (false) Turns logging on or off. @option settings [String] :broker (nil) Broker name (use if you intend to use broker-specific features). @option settings [Fixnum] :frame_max (131072) Maximum frame size to use. If broker cannot support frames this large, broker’s maximum value will be used instead.
@param [Hash] settings
# File lib/amq/client/async/adapters/event_machine.rb, line 41 41: def self.connect(settings = {}, &block) 42: @settings = Settings.configure(settings) 43: 44: instance = EventMachine.connect(@settings[:host], @settings[:port], self, @settings) 45: instance.register_connection_callback(&block) 46: 47: instance 48: end
# File lib/amq/client/async/adapters/event_machine.rb, line 140 140: def initialize(*args) 141: super(*args) 142: 143: self.logger = self.class.logger 144: 145: # channel => collected frames. MK. 146: @frames = Hash.new { Array.new } 147: @channels = Hash.new 148: @callbacks = Hash.new 149: 150: opening! 151: 152: # track TCP connection state, used to detect initial TCP connection failures. 153: @tcp_connection_established = false 154: @tcp_connection_failed = false 155: @intentionally_closing_connection = false 156: 157: # EventMachine::Connection's and Adapter's constructors arity 158: # make it easier to use *args. MK. 159: @settings = Settings.configure(args.first) 160: @on_tcp_connection_failure = @settings[:on_tcp_connection_failure] || Proc.new { |settings| 161: raise self.class.tcp_connection_failure_exception_class.new(settings) 162: } 163: @on_possible_authentication_failure = @settings[:on_possible_authentication_failure] || Proc.new { |settings| 164: raise self.class.authentication_failure_exception_class.new(settings) 165: } 166: 167: @mechanism = "PLAIN" 168: @locale = @settings.fetch(:locale, "en_GB") 169: @client_properties = Settings.client_properties.merge(@settings.fetch(:client_properties, Hash.new)) 170: 171: @auto_recovery = (!!@settings[:auto_recovery]) 172: 173: self.reset 174: self.set_pending_connect_timeout((@settings[:timeout] || 3).to_f) unless defined?(JRUBY_VERSION) 175: 176: if self.heartbeat_interval > 0 177: self.initialize_heartbeat_sender 178: end 179: end
Whether we are in authentication state (after TCP connection was estabilished but before broker authenticated us).
@return [Boolean] @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 199 199: def authenticating? 200: @authenticating 201: end
@private
# File lib/amq/client/async/adapters/event_machine.rb, line 278 278: def close_connection(*args) 279: @intentionally_closing_connection = true 280: 281: super(*args) 282: end
Called by EventMachine reactor once TCP connection is successfully estabilished. @private
# File lib/amq/client/async/adapters/event_machine.rb, line 246 246: def connection_completed 247: # we only can safely set this value here because EventMachine is a lovely piece of 248: # software that calls #post_init before #unbind even when TCP connection 249: # fails. MK. 250: @tcp_connection_established = true 251: @periodic_reconnection_timer.cancel if @periodic_reconnection_timer 252: 253: 254: # again, this is because #unbind is called in different situations 255: # and there is no easy way to tell initial connection failure 256: # from connection loss. Not in EventMachine 0.12.x, anyway. MK. 257: 258: if @had_successfully_connected_before 259: @recovered = true 260: 261: 262: self.start_automatic_recovery 263: self.upgrade_to_tls_if_necessary 264: end 265: 266: # now we can set it. MK. 267: @had_successfully_connected_before = true 268: @reconnecting = false 269: @handling_skipped_hearbeats = false 270: @last_server_heartbeat = Time.now 271: 272: self.initialize_heartbeat_sender if self.heartbeat_interval > 0 273: 274: self.handshake 275: end
Called by AMQ::Client::Connection after we receive connection.open-ok. @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 334 334: def connection_successful 335: @authenticating = false 336: opened! 337: 338: @connection_deferrable.succeed 339: end
Called by AMQ::Client::Connection after we receive connection.close-ok.
@api public
# File lib/amq/client/async/adapters/event_machine.rb, line 345 345: def disconnection_successful 346: @disconnection_deferrable.succeed 347: 348: # true for "after writing buffered data" 349: self.close_connection(true) 350: self.reset 351: closed! 352: end
For EventMachine adapter, this is a no-op. @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 185 185: def establish_connection(settings) 186: # Unfortunately there doesn't seem to be any sane way 187: # how to get EventMachine connect to the instance level. 188: end
Called when time since last server heartbeat received is greater or equal to the heartbeat interval set via :heartbeat_interval option on connection.
@api plugin
# File lib/amq/client/async/adapters/event_machine.rb, line 358 358: def handle_skipped_hearbeats 359: if !@handling_skipped_hearbeats && @tcp_connection_established && !@intentionally_closing_connection 360: @handling_skipped_hearbeats = true 361: @heartbeats_timer.cancel 362: 363: self.run_skipped_heartbeats_callbacks 364: end 365: end
@private
# File lib/amq/client/async/adapters/event_machine.rb, line 368 368: def initialize_heartbeat_sender 369: @last_server_heartbeat = Time.now 370: @heartbeats_timer = EventMachine::PeriodicTimer.new(self.heartbeat_interval, &method(:send_heartbeat)) 371: end
Defines a callback that will be run when broker confirms connection termination (client receives connection.close-ok). You can define more than one callback.
@api public
# File lib/amq/client/async/adapters/event_machine.rb, line 119 119: def on_closed(&block) 120: @disconnection_deferrable.callback(&block) 121: end
Defines a callback that will be executed when AMQP connection is considered open: client and broker has agreed on max channel identifier and maximum allowed frame size and authentication succeeds. You can define more than one callback.
@see on_possible_authentication_failure @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 110 110: def on_open(&block) 111: @connection_deferrable.callback(&block) 112: end
Periodically try to reconnect.
@param [Fixnum] period Period of time, in seconds, to wait before reconnection attempt. @param [Boolean] force If true, enforces immediate reconnection. @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 90 90: def periodically_reconnect(period = 5) 91: @reconnecting = true 92: self.reset 93: 94: @periodic_reconnection_timer = EventMachine::PeriodicTimer.new(period) { 95: EventMachine.reconnect(@settings[:host], @settings[:port], self) 96: } 97: end
EventMachine reactor callback. Is run when TCP connection is estabilished but before resumption of the network loop. Note that this includes cases when TCP connection has failed. @private
# File lib/amq/client/async/adapters/event_machine.rb, line 228 228: def post_init 229: reset 230: 231: # note that upgrading to TLS in #connection_completed causes 232: # Erlang SSL app that RabbitMQ relies on to report 233: # error on TCP connection <0.1465.0>:{ssl_upgrade_error,"record overflow"} 234: # and close TCP connection down. Investigation of this issue is likely 235: # to take some time and to not be worth in as long as #post_init 236: # works fine. MK. 237: upgrade_to_tls_if_necessary 238: rescue Exception => error 239: raise error 240: end
EventMachine receives data in chunks, sometimes those chunks are smaller than the size of AMQP frame. That’s why you need to add some kind of buffer.
@private
# File lib/amq/client/async/adapters/event_machine.rb, line 324 324: def receive_data(chunk) 325: @chunk_buffer << chunk 326: while frame = get_next_frame 327: self.receive_frame(AMQ::Client::Framing::String::Frame.decode(frame)) 328: end 329: end
Reconnect after a period of wait.
@param [Fixnum] period Period of time, in seconds, to wait before reconnection attempt. @param [Boolean] force If true, enforces immediate reconnection. @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 55 55: def reconnect(force = false, period = 5) 56: if @reconnecting and not force 57: EventMachine::Timer.new(period) { 58: reconnect(true, period) 59: } 60: return 61: end 62: 63: if !@reconnecting 64: @reconnecting = true 65: self.reset 66: end 67: 68: EventMachine.reconnect(@settings[:host], @settings[:port], self) 69: end
Similar to #, but uses different connection settings @see # @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 74 74: def reconnect_to(settings, period = 5) 75: if !@reconnecting 76: @reconnecting = true 77: self.reset 78: end 79: 80: @settings = Settings.configure(settings) 81: EventMachine.reconnect(@settings[:host], @settings[:port], self) 82: end
@see # @private
# File lib/amq/client/async/adapters/event_machine.rb, line 126 126: def register_connection_callback(&block) 127: unless block.nil? 128: # delay calling block we were given till after we receive 129: # connection.open-ok. Connection will notify us when 130: # that happens. 131: self.on_open do 132: block.call(self) 133: end 134: end 135: end
IS TCP connection estabilished and currently active? @return [Boolean] @api public
# File lib/amq/client/async/adapters/event_machine.rb, line 206 206: def tcp_connection_established? 207: @tcp_connection_established 208: end
Called by EventMachine reactor when
We close TCP connection down
Our peer closes TCP connection down
There is a network connection issue
Initial TCP connection fails
@private
# File lib/amq/client/async/adapters/event_machine.rb, line 291 291: def unbind(exception = nil) 292: if !@tcp_connection_established && !@had_successfully_connected_before && !@intentionally_closing_connection 293: @tcp_connection_failed = true 294: logger.error "[amqp] Detected TCP connection failure" 295: self.tcp_connection_failed 296: end 297: 298: closing! 299: @tcp_connection_established = false 300: 301: self.handle_connection_interruption if @reconnecting 302: @disconnection_deferrable.succeed 303: 304: closed! 305: 306: 307: self.tcp_connection_lost if !@intentionally_closing_connection && @had_successfully_connected_before 308: 309: # since AMQP spec dictates that authentication failure is a protocol exception 310: # and protocol exceptions result in connection closure, check whether we are 311: # in the authentication stage. If so, it is likely to signal an authentication 312: # issue. Java client behaves the same way. MK. 313: if authenticating? && !@intentionally_closing_connection 314: @on_possible_authentication_failure.call(@settings) if @on_possible_authentication_failure 315: end 316: end
# File lib/amq/client/async/adapters/event_machine.rb, line 403 403: def reset 404: @size = 0 405: @payload = "" 406: @frames = Array.new 407: 408: @chunk_buffer = "" 409: @connection_deferrable = EventMachine::DefaultDeferrable.new 410: @disconnection_deferrable = EventMachine::DefaultDeferrable.new 411: 412: # used to track down whether authentication succeeded. AMQP 0.9.1 dictates 413: # that on authentication failure broker must close TCP connection without sending 414: # any more data. This is why we need to explicitly track whether we are past 415: # authentication stage to signal possible authentication failures. 416: @authenticating = false 417: end
# File lib/amq/client/async/adapters/event_machine.rb, line 419 419: def upgrade_to_tls_if_necessary 420: tls_options = @settings[:ssl] 421: 422: if tls_options.is_a?(Hash) 423: start_tls(tls_options) 424: elsif tls_options 425: start_tls 426: end 427: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.