protobuf 3.3.4 → 3.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -17,9 +17,9 @@ module Protobuf
17
17
  :request => nil, # The request object sent by the client
18
18
  :request_type => nil, # The request type expected by the client
19
19
  :response_type => nil, # The response type expected by the client
20
- :timeout => 300, # The default timeout for the request, also handled by client.rb
20
+ :timeout => nil, # The timeout for the request, also handled by client.rb
21
21
  :client_host => nil, # The hostname or address of this client
22
- :first_alive_load_balance => false, # Do we want to use check_avail frames before request
22
+ :first_alive_load_balance => false, # Do we want to use check_avail frames before request
23
23
  }
24
24
 
25
25
  class Base
@@ -135,12 +135,20 @@ module Protobuf
135
135
  complete
136
136
  end
137
137
 
138
+ def timeout
139
+ if options[:timeout]
140
+ options[:timeout]
141
+ else
142
+ 300 # seconds
143
+ end
144
+ end
145
+
138
146
  # Wrap the given block in a timeout of the configured number of seconds.
139
147
  #
140
148
  def timeout_wrap(&block)
141
- ::Timeout.timeout(options[:timeout], &block)
149
+ ::Timeout.timeout(timeout, &block)
142
150
  rescue ::Timeout::Error
143
- fail(:RPC_FAILED, "The server took longer than #{options[:timeout]} seconds to respond")
151
+ fail(:RPC_FAILED, "The server took longer than #{timeout} seconds to respond")
144
152
  end
145
153
 
146
154
  def validate_request_type!
@@ -8,6 +8,7 @@ module Protobuf
8
8
  class Zmq < Base
9
9
  RequestTimeout = Class.new(RuntimeError)
10
10
  ZmqRecoverableError = Class.new(RuntimeError)
11
+ ZmqEagainError = Class.new(RuntimeError)
11
12
 
12
13
  ##
13
14
  # Included Modules
@@ -58,6 +59,13 @@ module Protobuf
58
59
  ##
59
60
  # Private Instance methods
60
61
  #
62
+ def check_available_rcv_timeout
63
+ @check_available_rcv_timeout ||= [ENV["PB_ZMQ_CLIENT_CHECK_AVAILABLE_RCV_TIMEOUT"].to_i, 200].max
64
+ end
65
+
66
+ def check_available_snd_timeout
67
+ @check_available_snd_timeout ||= [ENV["PB_ZMQ_CLIENT_CHECK_AVAILABLE_SND_TIMEOUT"].to_i, 200].max
68
+ end
61
69
 
62
70
  def close_connection
63
71
  # The socket is automatically closed after every request.
@@ -80,6 +88,8 @@ module Protobuf
80
88
  if first_alive_load_balance?
81
89
  begin
82
90
  check_available_response = ""
91
+ socket.setsockopt(::ZMQ::RCVTIMEO, check_available_rcv_timeout)
92
+ socket.setsockopt(::ZMQ::SNDTIMEO, check_available_snd_timeout)
83
93
  zmq_recoverable_error_check(socket.send_string(::Protobuf::Rpc::Zmq::CHECK_AVAILABLE_MESSAGE), :socket_send_string)
84
94
  zmq_recoverable_error_check(socket.recv_string(check_available_response), :socket_recv_string)
85
95
 
@@ -88,6 +98,9 @@ module Protobuf
88
98
  end
89
99
  rescue ZmqRecoverableError
90
100
  socket = nil # couldn't make a connection and need to try again
101
+ else
102
+ socket.setsockopt(::ZMQ::RCVTIMEO, -1)
103
+ socket.setsockopt(::ZMQ::SNDTIMEO, -1)
91
104
  end
92
105
  end
93
106
  end
@@ -163,11 +176,10 @@ module Protobuf
163
176
  #
164
177
  def send_request_with_lazy_pirate
165
178
  attempt = 0
166
- timeout = options[:timeout].to_f
167
179
 
168
180
  begin
169
181
  attempt += 1
170
- send_request_with_timeout(timeout, attempt)
182
+ send_request_with_timeout(attempt)
171
183
  parse_response
172
184
  rescue RequestTimeout
173
185
  retry if attempt < CLIENT_RETRIES
@@ -175,23 +187,45 @@ module Protobuf
175
187
  end
176
188
  end
177
189
 
178
- def send_request_with_timeout(timeout, attempt = 0)
179
- socket = create_socket
190
+ def rcv_timeout
191
+ @rcv_timeout ||= begin
192
+ case
193
+ when options[:timeout] then
194
+ options[:timeout]
195
+ when ENV.has_key?("PB_ZMQ_CLIENT_RCV_TIMEOUT") then
196
+ ENV["PB_ZMQ_CLIENT_RCV_TIMEOUT"].to_i
197
+ else
198
+ 300_000 # 300 seconds
199
+ end
200
+ end
201
+ end
180
202
 
181
- poller = ::ZMQ::Poller.new
182
- poller.register_readable(socket)
203
+ def snd_timeout
204
+ @snd_timeout ||= begin
205
+ case
206
+ when options[:timeout] then
207
+ options[:timeout]
208
+ when ENV.has_key?("PB_ZMQ_CLIENT_SND_TIMEOUT") then
209
+ ENV["PB_ZMQ_CLIENT_SND_TIMEOUT"].to_i
210
+ else
211
+ 300_000 # 300 seconds
212
+ end
213
+ end
214
+ end
215
+
216
+ def send_request_with_timeout(attempt = 0)
217
+ socket = create_socket
218
+ socket.setsockopt(::ZMQ::RCVTIMEO, rcv_timeout)
219
+ socket.setsockopt(::ZMQ::SNDTIMEO, snd_timeout)
183
220
 
184
221
  logger.debug { sign_message("Sending Request (attempt #{attempt}, #{socket})") }
185
- zmq_error_check(socket.send_string(@request_data), :socket_send_string)
186
- logger.debug { sign_message("Waiting #{timeout} seconds for response (attempt #{attempt}, #{socket})") }
187
-
188
- if poller.poll(timeout * 1000) == 1
189
- zmq_error_check(socket.recv_string(@response_data = ""), :socket_recv_string)
190
- logger.debug { sign_message("Response received (attempt #{attempt}, #{socket})") }
191
- else
192
- logger.debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
193
- raise RequestTimeout
194
- end
222
+ zmq_eagain_error_check(socket.send_string(@request_data), :socket_send_string)
223
+ logger.debug { sign_message("Waiting #{rcv_timeout}ms for response (attempt #{attempt}, #{socket})") }
224
+ zmq_eagain_error_check(socket.recv_string(@response_data = ""), :socket_recv_string)
225
+ logger.debug { sign_message("Response received (attempt #{attempt}, #{socket})") }
226
+ rescue ZmqEagainError
227
+ logger.debug { sign_message("Timed out waiting for response (attempt #{attempt}, #{socket})") }
228
+ raise RequestTimeout
195
229
  ensure
196
230
  logger.debug { sign_message("Closing Socket") }
197
231
  zmq_error_check(socket.close, :socket_close) if socket
@@ -221,6 +255,24 @@ module Protobuf
221
255
  self.class.zmq_context
222
256
  end
223
257
 
258
+ def zmq_eagain_error_check(return_code, source)
259
+ unless ::ZMQ::Util.resultcode_ok?(return_code || -1)
260
+ if ::ZMQ::Util.errno == ::ZMQ::EAGAIN
261
+ raise ZmqEagainError, <<-ERROR
262
+ Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
263
+
264
+ #{caller(1).join($/)}
265
+ ERROR
266
+ else
267
+ raise <<-ERROR
268
+ Last ZMQ API call to #{source} failed with "#{::ZMQ::Util.error_string}".
269
+
270
+ #{caller(1).join($/)}
271
+ ERROR
272
+ end
273
+ end
274
+ end
275
+
224
276
  def zmq_error_check(return_code, source)
225
277
  unless ::ZMQ::Util.resultcode_ok?(return_code || -1)
226
278
  raise <<-ERROR
@@ -1,3 +1,3 @@
1
1
  module Protobuf
2
- VERSION = '3.3.4'
2
+ VERSION = '3.3.5'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protobuf
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.4
4
+ version: 3.3.5
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-09-15 00:00:00.000000000 Z
15
+ date: 2014-09-16 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: activesupport
@@ -407,7 +407,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
407
407
  version: '0'
408
408
  segments:
409
409
  - 0
410
- hash: 3745042984186986363
410
+ hash: -3081500598642706001
411
411
  required_rubygems_version: !ruby/object:Gem::Requirement
412
412
  none: false
413
413
  requirements:
@@ -416,7 +416,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
416
416
  version: '0'
417
417
  segments:
418
418
  - 0
419
- hash: 3745042984186986363
419
+ hash: -3081500598642706001
420
420
  requirements: []
421
421
  rubyforge_project:
422
422
  rubygems_version: 1.8.24