amq-client 0.7.0.alpha5 → 0.7.0.alpha6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -1
- data/examples/eventmachine_adapter/connection_failure_callback.rb +1 -1
- data/examples/eventmachine_adapter/connection_failure_exception.rb +1 -1
- data/examples/eventmachine_adapter/connection_loss_handler.rb +1 -1
- data/lib/amq/client/adapters/event_machine.rb +28 -7
- data/lib/amq/client/connection.rb +20 -12
- data/lib/amq/client/version.rb +1 -1
- metadata +6 -6
data/Gemfile
CHANGED
@@ -19,7 +19,7 @@ EM.run do
|
|
19
19
|
:vhost => "/amq_client_testbed",
|
20
20
|
:user => "amq_client_gem",
|
21
21
|
:password => "amq_client_gem_password",
|
22
|
-
:
|
22
|
+
:timeout => 0.3,
|
23
23
|
:on_tcp_connection_failure => Proc.new { |settings| puts "Failed to connect, as expected"; EM.stop }) do |client|
|
24
24
|
raise "Connected, authenticated. This is not what this example is supposed to do!"
|
25
25
|
end
|
@@ -20,7 +20,7 @@ begin
|
|
20
20
|
:vhost => "/amq_client_testbed",
|
21
21
|
:user => "amq_client_gem",
|
22
22
|
:password => "amq_client_gem_password",
|
23
|
-
:
|
23
|
+
:timeout => 0.3) do |client|
|
24
24
|
raise "Connected, authenticated. This is not what this example is supposed to do!"
|
25
25
|
end
|
26
26
|
end
|
@@ -17,7 +17,7 @@ EM.run do
|
|
17
17
|
:vhost => "/amq_client_testbed",
|
18
18
|
:user => "amq_client_gem",
|
19
19
|
:password => "amq_client_gem_password",
|
20
|
-
:
|
20
|
+
:timeout => 0.3,
|
21
21
|
:on_tcp_connection_failure => Proc.new { |settings| puts "Failed to connect, this was NOT expected"; EM.stop }) do |client|
|
22
22
|
|
23
23
|
client.on_tcp_connection_loss do |cl, settings|
|
@@ -7,7 +7,7 @@ require "amq/client/framing/string/frame"
|
|
7
7
|
module AMQ
|
8
8
|
module Client
|
9
9
|
class EventMachineClient < EM::Connection
|
10
|
-
|
10
|
+
# @private
|
11
11
|
class Deferrable
|
12
12
|
include EventMachine::Deferrable
|
13
13
|
end
|
@@ -25,15 +25,19 @@ module AMQ
|
|
25
25
|
#
|
26
26
|
|
27
27
|
def self.connect(settings = nil, &block)
|
28
|
-
@settings =
|
28
|
+
@settings = Settings.configure(settings)
|
29
29
|
|
30
|
-
instance = EventMachine.connect(settings[:host], settings[:port], self, settings)
|
30
|
+
instance = EventMachine.connect(@settings[:host], @settings[:port], self, @settings)
|
31
31
|
instance.register_connection_callback(&block)
|
32
32
|
|
33
33
|
instance
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
# Reconnect after a period of wait.
|
37
|
+
#
|
38
|
+
# @param [Fixnum] period Period of time, in seconds, to wait before reconnection attempt.
|
39
|
+
# @param [Boolean] force If true, enforces immediate reconnection.
|
40
|
+
# @api public
|
37
41
|
def reconnect(period = 5, force = false)
|
38
42
|
if @reconnecting and not force
|
39
43
|
EventMachine::Timer.new(period) {
|
@@ -51,12 +55,15 @@ module AMQ
|
|
51
55
|
self.reconnect(@settings[:host], @settings[:port])
|
52
56
|
end
|
53
57
|
|
54
|
-
|
58
|
+
# For EventMachine adapter, this is a no-op.
|
59
|
+
# @api public
|
55
60
|
def establish_connection(settings)
|
56
61
|
# Unfortunately there doesn't seem to be any sane way
|
57
62
|
# how to get EventMachine connect to the instance level.
|
58
63
|
end
|
59
64
|
|
65
|
+
# @see #on_connection
|
66
|
+
# @private
|
60
67
|
def register_connection_callback(&block)
|
61
68
|
unless block.nil?
|
62
69
|
# delay calling block we were given till after we receive
|
@@ -91,6 +98,8 @@ module AMQ
|
|
91
98
|
|
92
99
|
self.reset
|
93
100
|
|
101
|
+
self.set_pending_connect_timeout((@settings[:timeout] || 3).to_f)
|
102
|
+
|
94
103
|
if self.heartbeat_interval > 0
|
95
104
|
@last_server_heartbeat = Time.now
|
96
105
|
EventMachine.add_periodic_timer(self.heartbeat_interval, &method(:send_heartbeat))
|
@@ -100,11 +109,18 @@ module AMQ
|
|
100
109
|
|
101
110
|
alias send_raw send_data
|
102
111
|
|
103
|
-
|
112
|
+
# Whether we are in authentication state (after TCP connection was estabilished
|
113
|
+
# but before broker authenticated us).
|
114
|
+
#
|
115
|
+
# @return [Boolean]
|
116
|
+
# @api public
|
104
117
|
def authenticating?
|
105
118
|
@authenticating
|
106
119
|
end # authenticating?
|
107
120
|
|
121
|
+
# IS TCP connection estabilished and currently active?
|
122
|
+
# @return [Boolean]
|
123
|
+
# @api public
|
108
124
|
def tcp_connection_established?
|
109
125
|
@tcp_connection_established
|
110
126
|
end # tcp_connection_established?
|
@@ -116,6 +132,7 @@ module AMQ
|
|
116
132
|
# EventMachine reactor callback. Is run when TCP connection is estabilished
|
117
133
|
# but before resumption of the network loop. Note that this includes cases
|
118
134
|
# when TCP connection has failed.
|
135
|
+
# @private
|
119
136
|
def post_init
|
120
137
|
reset
|
121
138
|
|
@@ -131,6 +148,7 @@ module AMQ
|
|
131
148
|
end # post_init
|
132
149
|
|
133
150
|
# Called by EventMachine reactor once TCP connection is successfully estabilished.
|
151
|
+
# @private
|
134
152
|
def connection_completed
|
135
153
|
# we only can safely set this value here because EventMachine is a lovely piece of
|
136
154
|
# software that calls #post_init before #unbind even when TCP connection
|
@@ -146,6 +164,7 @@ module AMQ
|
|
146
164
|
self.handshake
|
147
165
|
end
|
148
166
|
|
167
|
+
# @private
|
149
168
|
def close_connection(*args)
|
150
169
|
@intentionally_closing_connection = true
|
151
170
|
|
@@ -158,7 +177,8 @@ module AMQ
|
|
158
177
|
# * Our peer closes TCP connection down
|
159
178
|
# * There is a network connection issue
|
160
179
|
# * Initial TCP connection fails
|
161
|
-
|
180
|
+
# @private
|
181
|
+
def unbind(exception = nil)
|
162
182
|
if !@tcp_connection_established && !@had_successfull_connected_before
|
163
183
|
@tcp_connection_failed = true
|
164
184
|
self.tcp_connection_failed
|
@@ -193,6 +213,7 @@ module AMQ
|
|
193
213
|
# EventMachine receives data in chunks, sometimes those chunks are smaller
|
194
214
|
# than the size of AMQP frame. That's why you need to add some kind of buffer.
|
195
215
|
#
|
216
|
+
# @private
|
196
217
|
def receive_data(chunk)
|
197
218
|
@chunk_buffer << chunk
|
198
219
|
while frame = get_next_frame
|
@@ -83,7 +83,7 @@ module AMQ
|
|
83
83
|
|
84
84
|
|
85
85
|
|
86
|
-
|
86
|
+
# @api public
|
87
87
|
def initialize(client, mechanism, response, locale, client_properties = nil)
|
88
88
|
@mechanism = mechanism
|
89
89
|
@response = response
|
@@ -111,7 +111,7 @@ module AMQ
|
|
111
111
|
self.define_callback(:close) { |exception| raise(exception) }
|
112
112
|
end
|
113
113
|
|
114
|
-
|
114
|
+
# @api public
|
115
115
|
def settings
|
116
116
|
@client.settings
|
117
117
|
end # settings
|
@@ -124,6 +124,7 @@ module AMQ
|
|
124
124
|
|
125
125
|
# Sends connection.open to the server.
|
126
126
|
#
|
127
|
+
# @api public
|
127
128
|
# @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.4.2.7)
|
128
129
|
def open(vhost = "/")
|
129
130
|
@client.send Protocol::Connection::Open.encode(vhost)
|
@@ -132,13 +133,14 @@ module AMQ
|
|
132
133
|
|
133
134
|
# Sends connection.close to the server.
|
134
135
|
#
|
136
|
+
# @api public
|
135
137
|
# @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.4.2.9)
|
136
138
|
def close(reply_code = 200, reply_text = "Goodbye", class_id = 0, method_id = 0)
|
137
139
|
@client.send Protocol::Connection::Close.encode(reply_code, reply_text, class_id, method_id)
|
138
140
|
closing!
|
139
141
|
end
|
140
142
|
|
141
|
-
|
143
|
+
# @api public
|
142
144
|
def reset_state!
|
143
145
|
end # reset_state!
|
144
146
|
|
@@ -149,22 +151,25 @@ module AMQ
|
|
149
151
|
#
|
150
152
|
|
151
153
|
|
152
|
-
# Handles
|
154
|
+
# Handles Connection.Start.
|
153
155
|
#
|
156
|
+
# @api plugin
|
154
157
|
# @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.4.2.1.)
|
155
158
|
def start_ok(method)
|
156
159
|
@server_properties = method.server_properties
|
157
160
|
|
158
|
-
#
|
161
|
+
# It's not clear whether we should transition to :opening state here
|
159
162
|
# or in #open but in case authentication fails, it would be strange to have
|
160
163
|
# @status undefined. So lets do this. MK.
|
161
164
|
opening!
|
165
|
+
|
162
166
|
@client.send Protocol::Connection::StartOk.encode(@client_properties, @mechanism, @response, @locale)
|
163
167
|
end
|
164
168
|
|
165
169
|
|
166
|
-
# Handles
|
170
|
+
# Handles Connection.Open-Ok.
|
167
171
|
#
|
172
|
+
# @api plugin
|
168
173
|
# @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.4.2.8.)
|
169
174
|
def handle_open_ok(method)
|
170
175
|
@known_hosts = method.known_hosts
|
@@ -175,8 +180,9 @@ module AMQ
|
|
175
180
|
@client.connection_successful if @client.respond_to?(:connection_successful)
|
176
181
|
end
|
177
182
|
|
178
|
-
# Handles
|
183
|
+
# Handles Connection.Tune-Ok.
|
179
184
|
#
|
185
|
+
# @api plugin
|
180
186
|
# @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.4.2.6)
|
181
187
|
def handle_tune(method)
|
182
188
|
@channel_max = method.channel_max
|
@@ -187,27 +193,29 @@ module AMQ
|
|
187
193
|
end # handle_tune(method)
|
188
194
|
|
189
195
|
|
190
|
-
# Handles
|
196
|
+
# Handles Connection.Close.
|
191
197
|
#
|
198
|
+
# @api plugin
|
192
199
|
# @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.5.2.9)
|
193
200
|
def handle_close(method)
|
194
201
|
self.handle_connection_interruption
|
195
202
|
|
196
203
|
closed!
|
197
204
|
# TODO: use proper exception class, provide protocol class (we know method.class_id and method.method_id) as well!
|
198
|
-
|
199
|
-
self.error(
|
205
|
+
error = RuntimeError.new(method.reply_text)
|
206
|
+
self.error(error)
|
200
207
|
end
|
201
208
|
|
202
|
-
# Handles
|
209
|
+
# Handles Connection.Close-Ok.
|
203
210
|
#
|
211
|
+
# @api plugin
|
204
212
|
# @see http://bit.ly/htCzCX AMQP 0.9.1 protocol documentation (Section 1.4.2.10)
|
205
213
|
def handle_close_ok(method)
|
206
214
|
closed!
|
207
215
|
@client.disconnection_successful
|
208
216
|
end # handle_close_ok(method)
|
209
217
|
|
210
|
-
|
218
|
+
# @api plugin
|
211
219
|
def handle_connection_interruption
|
212
220
|
@channels.each { |n, c| c.handle_connection_interruption }
|
213
221
|
end # handle_connection_interruption
|
data/lib/amq/client/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amq-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.0.
|
4
|
+
version: 0.7.0.alpha6
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,12 +12,12 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain:
|
15
|
-
date: 2011-04-
|
15
|
+
date: 2011-04-22 00:00:00.000000000 +04:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: eventmachine
|
20
|
-
requirement: &
|
20
|
+
requirement: &2152430260 !ruby/object:Gem::Requirement
|
21
21
|
none: false
|
22
22
|
requirements:
|
23
23
|
- - ! '>='
|
@@ -25,10 +25,10 @@ dependencies:
|
|
25
25
|
version: '0'
|
26
26
|
type: :runtime
|
27
27
|
prerelease: false
|
28
|
-
version_requirements: *
|
28
|
+
version_requirements: *2152430260
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: amq-protocol
|
31
|
-
requirement: &
|
31
|
+
requirement: &2152682300 !ruby/object:Gem::Requirement
|
32
32
|
none: false
|
33
33
|
requirements:
|
34
34
|
- - ! '>='
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
version: '0'
|
37
37
|
type: :runtime
|
38
38
|
prerelease: false
|
39
|
-
version_requirements: *
|
39
|
+
version_requirements: *2152682300
|
40
40
|
description: amq-client supports multiple networking adapters (EventMachine, TCP sockets,
|
41
41
|
cool.io) and supposed to back more opinionated AMQP clients (such as amqp gem, bunny,
|
42
42
|
et cetera) or be used directly in cases when access to more advanced AMQP 0.9.1
|