right_support 2.5.4 → 2.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -99,7 +99,7 @@ end
99
99
  module RightSupport::DB
100
100
  # Exception that indicates database configuration info is missing.
101
101
  class MissingConfiguration < Exception; end
102
-
102
+ class UnsupportedRubyVersion < Exception; end
103
103
  # Base class for a column family in a keyspace
104
104
  # Used to access data persisted in Cassandra
105
105
  # Provides wrappers for Cassandra client methods
@@ -123,6 +123,11 @@ module RightSupport::DB
123
123
 
124
124
  @@connections = {}
125
125
 
126
+ # Depricate usage of CassandraModel under Ruby < 1.9
127
+ def inherited(base)
128
+ raise UnsupportedRubyVersion, "Support only Ruby >= 1.9" unless RUBY_VERSION >= "1.9"
129
+ end
130
+
126
131
  def config
127
132
  @@config
128
133
  end
@@ -270,7 +275,7 @@ module RightSupport::DB
270
275
  columns.merge!(chunk)
271
276
  if chunk.size == opt[:count]
272
277
  # Assume there are more chunks, use last key as start of next get
273
- opt[:start] = chunk.keys.sort.last
278
+ opt[:start] = chunk.keys.last
274
279
  else
275
280
  # This must be the last chunk
276
281
  break
@@ -409,7 +414,7 @@ module RightSupport::DB
409
414
  end
410
415
  if chunk.size == count
411
416
  # Assume there are more chunks, use last key as start of next get
412
- start = chunk.keys.sort.last
417
+ start = chunk.keys.last
413
418
  else
414
419
  # This must be the last chunk
415
420
  break
@@ -551,6 +556,7 @@ module RightSupport::DB
551
556
  config
552
557
  end
553
558
  end
559
+
554
560
  end # self
555
561
 
556
562
  attr_accessor :key, :attributes
@@ -29,7 +29,8 @@ module RightSupport::Net::LB
29
29
  # instead of putting it here.
30
30
  class EndpointsStack
31
31
  DEFAULT_YELLOW_STATES = 4
32
- DEFAULT_RESET_TIME = 300
32
+ DEFAULT_RESET_TIME = 60
33
+ INITIAL_N_LEVEL = 1
33
34
 
34
35
  def initialize(policy, endpoints, yellow_states=nil, reset_time=nil, on_health_change=nil)
35
36
  @policy = policy
@@ -38,7 +39,15 @@ module RightSupport::Net::LB
38
39
  @reset_time = reset_time || DEFAULT_RESET_TIME
39
40
  @on_health_change = on_health_change
40
41
  @min_n_level = 0
41
- endpoints.each { |ep| @endpoints[ep] = {:n_level => @min_n_level, :timestamp => 0} }
42
+ endpoints.each { |ep| @endpoints[ep] = {:n_level => INITIAL_N_LEVEL, :timestamp => 0} }
43
+ end
44
+
45
+ def inspect
46
+ "<#{self.class.name}: #{get_stats.inspect}>"
47
+ end
48
+
49
+ def to_s
50
+ inspect
42
51
  end
43
52
 
44
53
  def sweep
@@ -72,7 +81,7 @@ module RightSupport::Net::LB
72
81
 
73
82
  def state_color(n_level)
74
83
  color = 'green' if n_level == 0
75
- color = 'red' if n_level == @yellow_states
84
+ color = 'red' if n_level >= @yellow_states
76
85
  color = "yellow-#{n_level}" if n_level > 0 && n_level < @yellow_states
77
86
  color
78
87
  end
@@ -85,9 +94,13 @@ module RightSupport::Net::LB
85
94
  stats
86
95
  end
87
96
 
88
- def update!(endpoints)
89
- @endpoints.each { |k,v| endpoints.include?(k) ? endpoints.delete(k) : @endpoints.delete(k) }
90
- endpoints.each { |ep| @endpoints[ep] = {:n_level => @min_n_level, :timestamp => 0} }
97
+ # Replace the set of endpoints that this object knows about. If any
98
+ # endpoint in the new set is already being tracked, remember its
99
+ # health. For any new endpoint, set its health to INITIAL_N_LEVEL.
100
+
101
+ def update!(new_endpoints)
102
+ @endpoints.each { |k,v| new_endpoints.include?(k) ? new_endpoints.delete(k) : @endpoints.delete(k) }
103
+ new_endpoints.each { |ep| @endpoints[ep] = {:n_level => INITIAL_N_LEVEL, :timestamp => 0} }
91
104
  end
92
105
 
93
106
  # Return the logger that our surrounding policy uses
@@ -1,7 +1,21 @@
1
1
  module RightSupport::Net
2
2
  # Raised to indicate the (uncommon) error condition where a RequestBalancer rotated
3
- # through EVERY URL in a list without getting a non-nil, non-timeout response.
4
- class NoResult < Exception; end
3
+ # through EVERY URL in a list without getting a non-nil, non-timeout response.
4
+ #
5
+ # If the NoResult was due to a series of errors, then the #details attribute
6
+ # of this exception will let you access detailed information about the errors encountered
7
+ # while retrying the network request. #details is a Hash, the keys of which are endpoints,
8
+ # and the values of which are arrays of exceptions that we encountered while making
9
+ # requests to that endpoint.
10
+ class NoResult < Exception
11
+ # @return [Hash] a map of {endpoint => [exception_1, exception2, ...], ...}
12
+ attr_reader :details
13
+
14
+ def initialize(message, details={})
15
+ super(message)
16
+ @details = details
17
+ end
18
+ end
5
19
 
6
20
  # Utility class that allows network requests to be randomly distributed across
7
21
  # a set of network endpoints. Generally used for REST requests by passing an
@@ -38,7 +52,9 @@ module RightSupport::Net
38
52
  DEFAULT_FATAL_EXCEPTIONS = [
39
53
  NoMemoryError, SystemStackError, SignalException, SystemExit,
40
54
  ScriptError,
41
- #Subclasses of StandardError, which we can't mention directly
55
+ # Subclasses of StandardError. We can't include the base class directly as
56
+ # a fatal exception, because there are some retryable exceptions that derive
57
+ # from StandardError.
42
58
  ArgumentError, IndexError, LocalJumpError, NameError, RangeError,
43
59
  RegexpError, ThreadError, TypeError, ZeroDivisionError
44
60
  ]
@@ -186,22 +202,21 @@ module RightSupport::Net
186
202
  @policy.set_endpoints(@ips)
187
203
  end
188
204
 
189
- exceptions = []
205
+ exceptions = {}
190
206
  result = nil
191
207
  complete = false
192
208
  n = 0
193
209
 
194
210
  loop do
195
- if complete
196
- break
197
- else
211
+ if n > 0
198
212
  do_retry = @options[:retry] || DEFAULT_RETRY_PROC
199
213
  do_retry = do_retry.call(@ips || @endpoints, n) if do_retry.respond_to?(:call)
200
214
  break if (do_retry.is_a?(Integer) && n >= do_retry) || [nil, false].include?(do_retry)
201
215
  end
202
216
 
203
217
  endpoint, need_health_check = @policy.next
204
- raise NoResult, "No endpoints are available" unless endpoint
218
+ break unless endpoint
219
+
205
220
  n += 1
206
221
  t0 = Time.now
207
222
 
@@ -231,7 +246,8 @@ module RightSupport::Net
231
246
  raise(to_raise)
232
247
  else
233
248
  @policy.bad(endpoint, t0, Time.now)
234
- exceptions << e
249
+ exceptions[endpoint] ||= []
250
+ exceptions[endpoint] << e
235
251
  end
236
252
  end
237
253
 
@@ -239,14 +255,20 @@ module RightSupport::Net
239
255
 
240
256
  return result if complete
241
257
 
242
- exceptions = exceptions.map { |e| e.class.name }.uniq.join(', ')
243
- msg = "No available endpoints from #{(@ips || @endpoints).inspect}! Exceptions: #{exceptions}"
258
+ # Produce a summary message for the exception that gives a bit of detail
259
+ summary = []
260
+ exceptions.each_pair do |_, list|
261
+ list.each { |e| summary << e.class }
262
+ end
263
+ summary = summary.uniq.join(', ')
264
+ msg = "Request failed after #{n} tries to #{exceptions.keys.size} endpoints. Exceptions: #{summary}"
265
+
244
266
  logger.error "RequestBalancer: #{msg}"
245
- raise NoResult, msg
267
+ raise NoResult.new(msg, exceptions)
246
268
  end
247
269
 
248
270
  # Provide an interface so one can query the RequestBalancer for statistics on
249
- # it's endpoints. Merely proxies the balancing policy's get_stats method. If
271
+ # its endpoints. Merely proxies the balancing policy's get_stats method. If
250
272
  # no method exists in the balancing policy, a hash of endpoints with "n/a" is
251
273
  # returned.
252
274
  #
@@ -7,10 +7,10 @@ spec = Gem::Specification.new do |s|
7
7
  s.required_ruby_version = Gem::Requirement.new(">= 1.8.7")
8
8
 
9
9
  s.name = 'right_support'
10
- s.version = '2.5.4'
11
- s.date = '2012-10-05'
10
+ s.version = '2.5.5'
11
+ s.date = '2012-10-18'
12
12
 
13
- s.authors = ['Tony Spataro', 'Sergey Sergyenko', 'Ryan Williamson', 'Lee Kirchhoff', 'Sergey Enin']
13
+ s.authors = ['Tony Spataro', 'Sergey Sergyenko', 'Ryan Williamson', 'Lee Kirchhoff', 'Sergey Enin', 'Alexey Karpik']
14
14
  s.email = 'support@rightscale.com'
15
15
  s.homepage= 'https://github.com/rightscale/right_support'
16
16
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_support
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 17
5
5
  prerelease: false
6
6
  segments:
7
7
  - 2
8
8
  - 5
9
- - 4
10
- version: 2.5.4
9
+ - 5
10
+ version: 2.5.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tony Spataro
@@ -15,11 +15,12 @@ authors:
15
15
  - Ryan Williamson
16
16
  - Lee Kirchhoff
17
17
  - Sergey Enin
18
+ - Alexey Karpik
18
19
  autorequire:
19
20
  bindir: bin
20
21
  cert_chain: []
21
22
 
22
- date: 2012-10-05 00:00:00 -07:00
23
+ date: 2012-10-18 00:00:00 -07:00
23
24
  default_executable:
24
25
  dependencies: []
25
26