krakow 0.2.2 → 0.3.0

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.
Files changed (44) hide show
  1. data/CHANGELOG.md +16 -0
  2. data/CONTRIBUTING.md +25 -0
  3. data/LICENSE +13 -0
  4. data/README.md +62 -9
  5. data/krakow.gemspec +3 -1
  6. data/lib/krakow/command/cls.rb +3 -4
  7. data/lib/krakow/command/fin.rb +13 -4
  8. data/lib/krakow/command/identify.rb +22 -9
  9. data/lib/krakow/command/mpub.rb +14 -4
  10. data/lib/krakow/command/nop.rb +3 -4
  11. data/lib/krakow/command/pub.rb +15 -5
  12. data/lib/krakow/command/rdy.rb +13 -4
  13. data/lib/krakow/command/req.rb +14 -4
  14. data/lib/krakow/command/sub.rb +14 -4
  15. data/lib/krakow/command/touch.rb +13 -4
  16. data/lib/krakow/command.rb +25 -3
  17. data/lib/krakow/connection.rb +286 -60
  18. data/lib/krakow/connection_features/deflate.rb +26 -1
  19. data/lib/krakow/connection_features/snappy_frames.rb +34 -3
  20. data/lib/krakow/connection_features/ssl.rb +43 -1
  21. data/lib/krakow/connection_features.rb +1 -0
  22. data/lib/krakow/consumer.rb +162 -49
  23. data/lib/krakow/discovery.rb +17 -6
  24. data/lib/krakow/distribution/default.rb +61 -33
  25. data/lib/krakow/distribution.rb +107 -57
  26. data/lib/krakow/exceptions.rb +14 -0
  27. data/lib/krakow/frame_type/error.rb +13 -7
  28. data/lib/krakow/frame_type/message.rb +47 -4
  29. data/lib/krakow/frame_type/response.rb +14 -4
  30. data/lib/krakow/frame_type.rb +20 -8
  31. data/lib/krakow/producer/http.rb +95 -6
  32. data/lib/krakow/producer.rb +60 -17
  33. data/lib/krakow/utils/lazy.rb +99 -40
  34. data/lib/krakow/utils/logging.rb +11 -0
  35. data/lib/krakow/utils.rb +3 -0
  36. data/lib/krakow/version.rb +3 -1
  37. data/lib/krakow.rb +1 -0
  38. metadata +11 -11
  39. data/Gemfile +0 -5
  40. data/Gemfile.lock +0 -34
  41. data/test/spec.rb +0 -81
  42. data/test/specs/consumer.rb +0 -49
  43. data/test/specs/http_producer.rb +0 -123
  44. data/test/specs/producer.rb +0 -20
@@ -1,24 +1,47 @@
1
+ require 'openssl'
2
+ require 'krakow'
3
+
1
4
  module Krakow
2
5
  module ConnectionFeatures
6
+ # SSL functionality
3
7
  module Ssl
8
+ # SSL-able IO
4
9
  class Io
5
10
 
6
11
  attr_reader :_socket
7
12
 
13
+ # Create new SSL-able IO
14
+ #
15
+ # @param io [IO] IO to wrap
16
+ # @param args [Hash]
17
+ # @option args [Hash] :ssl_context
18
+ # @return [Io]
8
19
  def initialize(io, args={})
9
20
  ssl_socket_arguments = [io]
10
21
  if(args[:ssl_context])
11
- # ssl_socket_arguments << SSLContext.new
22
+ validate_ssl_args!(args[:ssl_context])
23
+ context = OpenSSL::SSL::SSLContext.new
24
+ context.cert = OpenSSL::X509::Certificate.new(File.open(args[:ssl_context][:certificate]))
25
+ context.key = OpenSSL::PKey::RSA.new(File.open(args[:ssl_context][:key]))
26
+ ssl_socket_arguments << context
12
27
  end
13
28
  @_socket = Celluloid::IO::SSLSocket.new(*ssl_socket_arguments)
14
29
  _socket.sync = true
15
30
  _socket.connect
16
31
  end
17
32
 
33
+ # Proxy to underlying socket
34
+ #
35
+ # @param args [Object]
36
+ # @return [Object]
18
37
  def method_missing(*args)
19
38
  _socket.send(*args)
20
39
  end
21
40
 
41
+ # Receive bytes from the IO
42
+ #
43
+ # @param len [Integer] nuber of bytes
44
+ # @return [String]
22
45
  def recv(len)
23
46
  str = readpartial(len)
24
47
  if(len > str.length)
@@ -27,6 +50,25 @@ module Krakow
27
50
  str
28
51
  end
29
52
 
53
+ private
54
+
55
+ # Validate the SSL configuration provided
56
+ #
57
+ # @param args [Hash]
58
+ # @option args [String] :certificate path to certificate
59
+ # @option args [String] :key path to key
60
+ # @raise [ArgumentError, LoadError]
61
+ def validate_ssl_args!(args)
62
+ [:key, :certificate].each do |arg_key|
63
+ unless(args.has_key?(arg_key))
64
+ raise ArgumentError.new "The `:ssl_context` option requires `#{arg_key.inspect}` to be set"
65
+ end
66
+ unless(File.readable?(args[arg_key]))
67
+ raise LoadError.new "Unable to read the `#{arg_key.inspect}` file from the `:ssl_context` arguments"
68
+ end
69
+ end
70
+ end
71
+
30
72
  end
31
73
  end
32
74
  end
@@ -1,6 +1,7 @@
1
1
  require 'krakow'
2
2
 
3
3
  module Krakow
4
+ # Features that wrap the connection
4
5
  module ConnectionFeatures
5
6
  autoload :SnappyFrames, 'krakow/connection_features/snappy_frames'
6
7
  autoload :Deflate, 'krakow/connection_features/deflate'
@@ -1,7 +1,13 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
4
+ # Consume messages from a server
2
5
  class Consumer
3
6
 
4
7
  include Utils::Lazy
8
+ # @!parse include Krakow::Utils::Lazy::InstanceMethods
9
+ # @!parse extend Krakow::Utils::Lazy::ClassMethods
10
+
5
11
  include Celluloid
6
12
 
7
13
  trap_exit :connection_failure
@@ -9,25 +15,43 @@ module Krakow
9
15
 
10
16
  attr_reader :connections, :discovery, :distribution, :queue
11
17
 
18
+ # @!group Attributes
19
+
20
+ # @!macro [attach] attribute
21
+ # @!method $1
22
+ # @return [$2] the $1 $0
23
+ # @!method $1?
24
+ # @return [TrueClass, FalseClass] truthiness of the $1 $0
25
+ attribute :topic, String, :required => true
26
+ attribute :channel, String, :required => true
27
+ attribute :host, String
28
+ attribute :port, [String, Integer]
29
+ attribute :nsqlookupd, [Array, String]
30
+ attribute :max_in_flight, Integer, :default => 1
31
+ attribute :backoff_interval, Numeric
32
+ attribute :discovery_interval, Numeric, :default => 30
33
+ attribute :discovery_jitter, Numeric, :default => 10.0
34
+ attribute :notifier, Celluloid::Actor
35
+ attribute :connection_options, Hash, :default => ->{ Hash.new }
36
+
37
+ # @!endgroup
38
+
12
39
  def initialize(args={})
13
40
  super
14
- required! :topic, :channel
15
- optional :host, :port, :nslookupd, :nsqlookupd, :max_in_flight, :backoff_interval, :discovery_interval, :notifier, :connection_features
16
- arguments[:max_in_flight] ||= 1
17
- arguments[:discovery_interval] ||= 30
18
- arguments[:connection_features] ||= {}
19
- arguments[:nsqlookupd] ||= arguments[:nslookupd]
41
+ arguments[:connection_options] = {:features => {}, :config => {}}.merge(
42
+ arguments[:connection_options] || {}
43
+ )
20
44
  @connections = {}
21
45
  @distribution = Distribution::Default.new(
22
46
  :max_in_flight => max_in_flight,
23
- :backoff_interval => backoff_interval
47
+ :backoff_interval => backoff_interval,
48
+ :consumer => current_actor
24
49
  )
25
50
  @queue = Queue.new
26
51
  if(nsqlookupd)
27
52
  debug "Connections will be established via lookup #{nsqlookupd.inspect}"
28
53
  @discovery = Discovery.new(:nsqlookupd => nsqlookupd)
29
- init!
30
- every(discovery_interval){ init! }
54
+ discover
31
55
  elsif(host && port)
32
56
  debug "Connection will be established via direct connection #{host}:#{port}"
33
57
  connection = build_connection(host, port, queue)
@@ -42,10 +66,22 @@ module Krakow
42
66
  end
43
67
  end
44
68
 
69
+ # Returns [Krakow::Connection] associated to key
70
+ #
71
+ # @param key [Object] identifier
72
+ # @return [Krakow::Connection] associated connection
73
+ def connection(key)
74
+ @connections[key]
75
+ end
76
+
77
+ # @return [String] stringify object
45
78
  def to_s
46
79
  "<#{self.class.name}:#{object_id} T:#{topic} C:#{channel}>"
47
80
  end
48
81
 
82
+ # Instance destructor
83
+ #
84
+ # @return [nil]
49
85
  def goodbye_my_love!
50
86
  debug 'Tearing down consumer'
51
87
  connections.values.each do |con|
@@ -53,43 +89,79 @@ module Krakow
53
89
  end
54
90
  distribution.terminate if distribution && distribution.alive?
55
91
  info 'Consumer torn down'
92
+ nil
56
93
  end
57
94
 
58
- # host:: remote address
59
- # port:: remote port
60
- # queue:: message store queue
61
- # Build new `Connection`
95
+ # Build a new [Krakow::Connection]
96
+ #
97
+ # @param host [String] remote host
98
+ # @param port [String, Integer] remote port
99
+ # @param queue [Queue] queue for messages
100
+ # @return [Krakow::Connection, nil] new connection or nil
62
101
  def build_connection(host, port, queue)
63
- connection = Connection.new(
64
- :host => host,
65
- :port => port,
66
- :queue => queue,
67
- :notifier => notifier,
68
- :features => connection_features,
69
- :callback => {
70
- :actor => current_actor,
71
- :method => :process_message
72
- }
73
- )
102
+ begin
103
+ connection = Connection.new(
104
+ :host => host,
105
+ :port => port,
106
+ :queue => queue,
107
+ :topic => topic,
108
+ :channel => channel,
109
+ :notifier => notifier,
110
+ :features => connection_options[:features],
111
+ :features_args => connection_options[:config],
112
+ :callbacks => {
113
+ :handle => {
114
+ :actor => current_actor,
115
+ :method => :process_message
116
+ },
117
+ :reconnect => {
118
+ :actor => current_actor,
119
+ :method => :connection_reconnect
120
+ }
121
+ }
122
+ )
123
+ rescue => e
124
+ error "Failed to build connection (host: #{host} port: #{port} queue: #{queue}) - #{e.class}: #{e}"
125
+ debug "#{e.class}: #{e}\n#{e.backtrace.join("\n")}"
126
+ nil
127
+ end
74
128
  end
75
129
 
76
- # message:: FrameType
77
- # connection:: Connection
78
- # Process message if required
130
+ # Process a given message if required
131
+ #
132
+ # @param message [Krakow::FrameType]
133
+ # @param connection [Krakow::Connection]
134
+ # @return [Krakow::FrameType]
79
135
  def process_message(message, connection)
80
136
  if(message.is_a?(FrameType::Message))
81
- distribution.register_message(message, connection)
137
+ distribution.register_message(message, connection.identifier)
138
+ message.origin = current_actor
82
139
  end
83
140
  message
84
141
  end
85
142
 
86
- # connection:: Connection
143
+ # Action to take when a connection has reconnected
144
+ #
145
+ # @param connection [Krakow::Connection]
146
+ # @return [nil]
147
+ def connection_reconnect(connection)
148
+ connection.transmit(Command::Sub.new(:topic_name => topic, :channel_name => channel))
149
+ distribution.set_ready_for(connection)
150
+ nil
151
+ end
152
+
87
153
  # Send RDY for connection based on distribution rules
154
+ #
155
+ # @param connection [Krakow::Connection]
156
+ # @return [nil]
88
157
  def update_ready!(connection)
89
158
  distribution.set_ready_for(connection)
159
+ nil
90
160
  end
91
161
 
92
- # Requests lookup and adds connections
162
+ # Initialize the consumer by starting lookup and adding connections
163
+ #
164
+ # @return [nil]
93
165
  def init!
94
166
  debug 'Running consumer `init!` connection builds'
95
167
  found = discovery.lookup(topic)
@@ -97,7 +169,7 @@ module Krakow
97
169
  connection = nil
98
170
  found.each do |node|
99
171
  debug "Processing discovery result: #{node.inspect}"
100
- key = "#{node[:broadcast_address]}_#{node[:tcp_port]}"
172
+ key = Connection.identifier(node[:broadcast_address], node[:tcp_port], topic, channel)
101
173
  unless(connections[key])
102
174
  connection = build_connection(node[:broadcast_address], node[:tcp_port], queue)
103
175
  info "Registered new connection #{connection}" if register(connection)
@@ -106,16 +178,27 @@ module Krakow
106
178
  end
107
179
  end
108
180
  distribution.redistribute! if connection
181
+ nil
182
+ end
183
+
184
+ # Start the discovery interval lookup
185
+ #
186
+ # @return [nil]
187
+ def discover
188
+ init!
189
+ after(discovery_interval + (discovery_jitter * rand)){ discover }
109
190
  end
110
191
 
111
- # connection:: Connection
112
- # Registers connection with subscription. Returns false if failed
192
+ # Register connection with distribution
193
+ #
194
+ # @param connection [Krakow::Connection]
195
+ # @return [TrueClass, FalseClass] true if subscription was successful
113
196
  def register(connection)
114
197
  begin
115
198
  connection.init!
116
199
  connection.transmit(Command::Sub.new(:topic_name => topic, :channel_name => channel))
117
200
  self.link connection
118
- connections["#{connection.host}_#{connection.port}"] = connection
201
+ connections[connection.identifier] = connection
119
202
  distribution.add_connection(connection)
120
203
  true
121
204
  rescue Error::BadResponse => e
@@ -125,40 +208,56 @@ module Krakow
125
208
  end
126
209
  end
127
210
 
128
- # con:: actor
129
- # reason:: Exception
130
- # Remove connection from register if found
131
- def connection_failure(con, reason)
211
+ # Remove connection references when connection is terminated
212
+ #
213
+ # @param actor [Object] terminated actor
214
+ # @param reason [Exception] reason for termination
215
+ # @return [nil]
216
+ def connection_failure(actor, reason)
132
217
  connections.delete_if do |key, value|
133
- if(value == con)
134
- warn "Connection failure detected. Removing connection: #{key}"
135
- distribution.remove_connection(con)
218
+ if(value == actor && reason.nil?)
219
+ warn "Connection failure detected. Removing connection: #{key} - #{reason || 'no reason provided'}"
220
+ begin
221
+ distribution.remove_connection(key)
222
+ rescue Error::ConnectionUnavailable, Error::ConnectionFailure
223
+ warn 'Caught connection unavailability'
224
+ end
225
+ distribution.redistribute!
136
226
  true
137
227
  end
138
228
  end
139
- distribution.redistribute!
229
+ nil
140
230
  end
141
231
 
142
- # message_id:: Message ID (or message if you want to be lazy)
143
232
  # Confirm message has been processed
233
+ #
234
+ # @param message_id [String, Krakow::FrameType::Message]
235
+ # @return [TrueClass]
236
+ # @raise [KeyError] connection not found
144
237
  def confirm(message_id)
145
238
  message_id = message_id.message_id if message_id.respond_to?(:message_id)
146
239
  begin
147
240
  distribution.in_flight_lookup(message_id) do |connection|
148
241
  distribution.unregister_message(message_id)
149
242
  connection.transmit(Command::Fin.new(:message_id => message_id))
150
- distribution.success(connection)
243
+ distribution.success(connection.identifier)
151
244
  update_ready!(connection)
152
245
  end
153
246
  true
154
- rescue => e
247
+ rescue KeyError => e
248
+ error "Message confirmation failed: #{e}"
155
249
  abort e
250
+ rescue Error::ConnectionUnavailable => e
251
+ retry
156
252
  end
157
253
  end
254
+ alias_method :finish, :confirm
158
255
 
159
- # message_id:: Message ID
160
- # timeout:: Requeue timeout (default is none)
161
- # Requeue message (processing failure)
256
+ # Requeue message (generally due to processing failure)
257
+ #
258
+ # @param message_id [String, Krakow::FrameType::Message]
259
+ # @param timeout [Numeric]
260
+ # @return [TrueClass]
162
261
  def requeue(message_id, timeout=0)
163
262
  message_id = message_id.message_id if message_id.respond_to?(:message_id)
164
263
  distribution.in_flight_lookup(message_id) do |connection|
@@ -169,11 +268,25 @@ module Krakow
169
268
  :timeout => timeout
170
269
  )
171
270
  )
172
- distribution.failure(connection)
271
+ distribution.failure(connection.identifier)
173
272
  update_ready!(connection)
174
273
  end
175
274
  true
176
275
  end
177
276
 
277
+ # Touch message (to extend timeout)
278
+ #
279
+ # @param message_id [String, Krakow::FrameType::Message]
280
+ # @return [TrueClass]
281
+ def touch(message_id)
282
+ message_id = message_id.message_id if message_id.respond_to?(:message_id)
283
+ distribution.in_flight_lookup(message_id) do |connection|
284
+ connection.transmit(
285
+ Command::Touch.new(:message_id => message_id)
286
+ )
287
+ end
288
+ true
289
+ end
290
+
178
291
  end
179
292
  end
@@ -1,19 +1,30 @@
1
1
  require 'uri'
2
2
  require 'http'
3
3
  require 'multi_json'
4
+ require 'krakow'
4
5
 
5
6
  module Krakow
7
+
8
+ # Provides queue topic discovery
6
9
  class Discovery
7
10
 
8
11
  include Utils::Lazy
9
12
 
10
- def initialize(args={})
11
- super
12
- required! :nsqlookupd
13
- end
13
+ # @!group Attributes
14
+
15
+ # @!macro [attach] attribute
16
+ # @!method $1
17
+ # @return [$2] the $1 $0
18
+ # @!method $1?
19
+ # @return [TrueClass, FalseClass] truthiness of the $1 $0
20
+ attribute :nsqlookupd, [Array, String], :required => true
21
+
22
+ # @!endgroup
14
23
 
15
- # topic:: Topic name
16
- # Return list of end points with given topic name available
24
+ # Get list of end points with given topic name available
25
+ #
26
+ # @param topic [String] topic name
27
+ # @return [Array<Hash>]
17
28
  def lookup(topic)
18
29
  result = [nsqlookupd].flatten.map do |location|
19
30
  uri = URI.parse(location)
@@ -1,5 +1,9 @@
1
+ require 'krakow'
2
+
1
3
  module Krakow
2
4
  class Distribution
5
+ # Default distribution implementation. This uses a round-robin
6
+ # approach for less than ideal states.
3
7
  class Default < Distribution
4
8
 
5
9
  attr_reader :less_than_ideal_stack, :watch_dog
@@ -9,7 +13,7 @@ module Krakow
9
13
  @ideal = registry.size < 1 ? 0 : max_in_flight / registry.size
10
14
  debug "Distribution calculated ideal: #{ideal}"
11
15
  if(less_than_ideal?)
12
- registry.each do |connection, reg_info|
16
+ registry.each do |connection_id, reg_info|
13
17
  reg_info[:ready] = 0
14
18
  end
15
19
  max_in_flight.times do
@@ -28,9 +32,9 @@ module Krakow
28
32
  @watch_dog = nil
29
33
  end
30
34
  connections.each do |connection|
31
- current_ready = ready_for(connection)
32
- calculate_ready!(connection)
33
- unless(current_ready == ready_for(connection))
35
+ current_ready = ready_for(connection.identifier)
36
+ calculate_ready!(connection.identifier)
37
+ unless(current_ready == ready_for(connection.identifier))
34
38
  debug "Redistribution ready setting update for connection #{connection}"
35
39
  set_ready_for(connection)
36
40
  end
@@ -38,12 +42,16 @@ module Krakow
38
42
  end
39
43
  end
40
44
 
41
- # Returns if `ideal` is less than 1
45
+ # Is ideal less than 1
46
+ #
47
+ # @return [TrueClass, FalseClass]
42
48
  def less_than_ideal?
43
49
  ideal < 1
44
50
  end
45
51
 
46
- # Returns next connection to receive RDY count
52
+ # Find next connection to receive RDY count
53
+ #
54
+ # @return [Krakow::Connection, nil]
47
55
  def less_than_ideal_ready!
48
56
  admit_defeat = false
49
57
  connection = nil
@@ -53,18 +61,24 @@ module Krakow
53
61
  admit_defeat = true
54
62
  end
55
63
  con = less_than_ideal_stack.pop
56
- connection = con unless registry_lookup(con)[:backoff_until] > Time.now.to_i
64
+ if(con)
65
+ unless(registry_lookup(con.identifier)[:backoff_until] > Time.now.to_i)
66
+ connection = con
67
+ end
68
+ end
57
69
  end
58
70
  if(connection)
59
- registry_lookup(connection)[:ready] = 1
71
+ registry_lookup(connection.identifier)[:ready] = 1
60
72
  connection
61
73
  end
62
74
  end
63
75
 
64
- # connection:: Connection
65
- # args:: optional args (:force)
66
- # Provides customized RDY set when less than ideal to round
67
- # robin through connections
76
+ # Adds extra functionality to provide round robin RDY setting
77
+ # when in less than ideal state
78
+ #
79
+ # @param connection [Krakow::Connection]
80
+ # @param args [Symbol]
81
+ # @return [Krakow::FrameType::Error, nil]
68
82
  def set_ready_for(connection, *args)
69
83
  super connection
70
84
  if(less_than_ideal? && !args.include?(:force))
@@ -79,51 +93,65 @@ module Krakow
79
93
  end
80
94
  end
81
95
 
82
- # connection:: Connection
83
96
  # Update connection ready count
84
- def calculate_ready!(connection)
85
- registry_info = registry_lookup(connection)
86
- unless(less_than_ideal?)
87
- registry_info[:ready] = ideal - registry_info[:in_flight]
88
- if(registry_info[:ready] < 0 || registry_info[:backoff_until] > Time.now.to_i)
89
- registry_info[:ready] = 0
90
- registry_info[:backoff_timer].cancel if registry[:backoff_timer]
91
- registry_info[:backoff_timer] = after(registry_info[:backoff_until] - Time.now.to_i) do
92
- calculate_ready!(connection)
93
- set_ready_for(conection) unless less_than_ideal?
97
+ # @param connection_identifier [String]
98
+ # @return [Integer, nil]
99
+ def calculate_ready!(connection_identifier)
100
+ begin
101
+ registry_info = registry_lookup(connection_identifier)
102
+ unless(less_than_ideal?)
103
+ registry_info[:ready] = ideal - registry_info[:in_flight]
104
+ if(registry_info[:ready] < 0 || registry_info[:backoff_until] > Time.now.to_i)
105
+ registry_info[:ready] = 0
106
+ registry_info[:backoff_timer].cancel if registry[:backoff_timer]
107
+ registry_info[:backoff_timer] = after(registry_info[:backoff_until] - Time.now.to_i) do
108
+ calculate_ready!(connection_identifier)
109
+ set_ready_for(connection_lookup(connection_identifier)) unless less_than_ideal?
110
+ end
94
111
  end
112
+ registry_info[:ready]
113
+ else
114
+ registry_info[:ready] = 0
95
115
  end
96
- registry_info[:ready]
97
- else
98
- registry_info[:ready] = 0
116
+ rescue Error::ConnectionFailure
117
+ warn 'Failed connection encountered!'
118
+ rescue Error::ConnectionUnavailable
119
+ warn 'Unavailable connection encountered!'
99
120
  end
100
121
  end
101
122
 
102
- # Returns all connections without RDY state
123
+ # All connections without RDY state
124
+ #
125
+ # @return [Array<Krakow::Connection>]
103
126
  def waiting_connections
104
- registry.find_all do |connection, info|
127
+ registry.find_all do |conn_id, info|
105
128
  info[:ready] < 1 && info[:in_flight] < 1 && info[:backoff_until] < Time.now.to_i
106
- end.map(&:first).compact
129
+ end.map{|conn_id, info| connection_lookup(conn_id) }.compact
107
130
  end
108
131
 
109
- # Returns all connections with RDY state
132
+ # All connections with RDY state
133
+ #
134
+ # @return [Array<Krakow::Connection>]
110
135
  def rdy_connections
111
- registry.find_all do |connection, info|
136
+ registry.find_all do |conn_id, info|
112
137
  info[:ready] > 0
113
- end.map(&:first).compact
138
+ end.map{|conn_id, info| connection_lookup(conn_id) }.compact
114
139
  end
115
140
 
116
141
  # Force a connection to give up RDY state so next in stack can receive
142
+ #
143
+ # @return [nil]
117
144
  def force_unready
118
145
  debug 'Forcing a connection into an unready state due to less than ideal state'
119
146
  connection = rdy_connections.shuffle.first
120
147
  if(connection)
121
148
  debug "Stripping RDY state from connection: #{connection}"
122
- calculate_ready!(connection)
149
+ calculate_ready!(connection.identifier)
123
150
  set_ready_for(connection)
124
151
  else
125
152
  warn "Failed to locate available connection for RDY aquisition!"
126
153
  end
154
+ nil
127
155
  end
128
156
 
129
157
  end