cb2 0.0.1 → 0.0.2

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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzM2YWYxM2YyMmMxMmQ4NWZkNjczYjM5OGQ3NDBlZTk4MjViODdlNw==
4
+ ZTE5OWQ3ZDliNTg4OGUyNjU4YTNiOGVkM2FjNzAwM2VkMTdiZWU4Zg==
5
5
  data.tar.gz: !binary |-
6
- YTcwMzhiMTAyMDk0Mjc5YzZkMWM0MzBmYmQ2OTM2ZGQ2NDJhMTE5OA==
6
+ ZDEzYjJjMTA5YTIxZDE2MDRkOWRiNzk0ZjQ3NDlkYzZhMmYwOTdiMA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MjYzYzVhNTFhNWJiMDgyMTBhZTMzYTg1Mjk5ZGFkZDRkMzM4MTY2YjdhMGI0
10
- YjY2MTJhMDY0MzdkZjAyZTk2M2MxYWFjMTc5OTIyZWY0YjVhYWVmYmU1MmM0
11
- ZDNhNWI4NWEwOGVhYmIyNTVmNmZlMDNhMjQwNmU0MTViNzAwMzE=
9
+ YTg1OGMwZjYzYTk5NTQ0NTQ4MDY2M2ZmNGZmOGZjZGQ4NmNjNmYwNGE4ZWRh
10
+ MjQyYjRlZTJhNDFiMDIzYzQxZjRjNTU4YTQzNDNjMzAzZTk1NzZhNmQ1MWZh
11
+ ZWI5MmFmN2MxMTEzOTczZWY0MGMwOWIwMzMyNWM0ZmJmNjgyYmQ=
12
12
  data.tar.gz: !binary |-
13
- NjY4OWQxMGZhYjI5OWFhYTk2ZWJkZGU4NDgwNTJiMDIyNjRmMmQ3OTk1OTRk
14
- ZTcwNjhiM2UxNzEzNzQ2MGFlZDZjNTQ0ZjkwOGUxZjEwYzYzMTgzYzkyNjE4
15
- N2UxZTU1ZTBlOGJhZjU4MWEzMzcxZTIwMzllMmFlMjRiMDYwNzQ=
13
+ MWQwYjA0Mzk1NTgxYWRiZmVkZmYwYzZlMDY5NTkwYTBlYWEzZDk5Mjc3ZTNl
14
+ MmE2ZjFmYTczODlmNjMyZWQyZTIyZmEyY2Y2OWNiMjU2MzczMDQ2MDBmYmYz
15
+ ZGRhZmNlMWNlMTkxZjQ2OGQyMjdlYjEzMzUzOGRjNWM2ZTU2NzE=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cb2 (0.0.1)
4
+ cb2 (0.0.2)
5
5
  redis (~> 3.1)
6
6
 
7
7
  GEM
@@ -10,6 +10,7 @@ GEM
10
10
  diff-lcs (1.2.5)
11
11
  rake (10.3.2)
12
12
  redis (3.1.0)
13
+ rr (1.1.2)
13
14
  rspec (3.1.0)
14
15
  rspec-core (~> 3.1.0)
15
16
  rspec-expectations (~> 3.1.0)
@@ -30,5 +31,6 @@ PLATFORMS
30
31
  DEPENDENCIES
31
32
  cb2!
32
33
  rake (> 0)
34
+ rr (~> 1.1)
33
35
  rspec (~> 3.1)
34
36
  timecop (~> 0.7)
data/lib/cb2.rb CHANGED
@@ -3,7 +3,8 @@ require "redis"
3
3
  module CB2
4
4
  end
5
5
 
6
- require "breaker"
7
- require "error"
8
- require "strategies/rolling_window"
9
- require "strategies/stub"
6
+ require "cb2/breaker"
7
+ require "cb2/error"
8
+ require "cb2/strategies/rolling_window"
9
+ require "cb2/strategies/percentage"
10
+ require "cb2/strategies/stub"
@@ -12,28 +12,43 @@ class CB2::Breaker
12
12
  end
13
13
 
14
14
  begin
15
+ process_count
15
16
  yield
16
17
  rescue => e
17
- strategy.process
18
+ process_error
18
19
  raise e
19
20
  end
20
21
  end
21
22
 
22
23
  def open?
23
24
  strategy.open?
25
+ rescue Redis::BaseError
26
+ false
27
+ end
28
+
29
+ def process_count
30
+ strategy.count if strategy.respond_to?(:count)
31
+ rescue Redis::BaseError
32
+ end
33
+
34
+ def process_error
35
+ strategy.error if strategy.respond_to?(:error)
36
+ rescue Redis::BaseError
24
37
  end
25
38
 
26
39
  def initialize_strategy(options)
27
40
  strategy_options = options.dup.merge(service: self.service)
28
41
 
29
- if options[:strategy].respond_to?(:open)
42
+ if options[:strategy].respond_to?(:open?)
30
43
  return options[:strategy].new(strategy_options)
31
44
  end
32
45
 
33
- case options[:strategy]
34
- when nil, :rolling_window
46
+ case options[:strategy].to_s
47
+ when "", "percentage"
48
+ CB2::Percentage.new(strategy_options)
49
+ when "rolling_window"
35
50
  CB2::RollingWindow.new(strategy_options)
36
- when nil, :stub
51
+ when "stub"
37
52
  CB2::Stub.new(strategy_options)
38
53
  end
39
54
  end
File without changes
@@ -0,0 +1,16 @@
1
+ class CB2::Percentage < CB2::RollingWindow
2
+ # keep a rolling window of successful calls too
3
+ def count
4
+ @current_count = increment_rolling_window(key("count"))
5
+ end
6
+
7
+ private
8
+
9
+ def should_open?(error_count)
10
+ # do not open until we have a reasonable number of requests
11
+ return false if @current_count < 5
12
+
13
+ error_perc = error_count * 100 / @current_count.to_f
14
+ return error_perc >= threshold
15
+ end
16
+ end
@@ -6,19 +6,42 @@ class CB2::RollingWindow
6
6
  @duration = options.fetch(:duration)
7
7
  @threshold = options.fetch(:threshold)
8
8
  @reenable_after = options.fetch(:reenable_after)
9
- @redis = Redis.current
9
+ @redis = options[:redis] || Redis.current
10
10
  end
11
11
 
12
12
  def open?
13
- redis.exists(cache_key)
13
+ last_open && last_open.to_i > (Time.now.to_i - reenable_after)
14
14
  end
15
15
 
16
16
  def open!
17
- redis.setex(cache_key, reenable_after, 1)
17
+ @last_open = Time.now.to_i
18
+ redis.set(key, @last_open)
18
19
  end
19
20
 
20
- def process
21
- key = "circuit-breaker-count-#{service}"
21
+ def half_open?
22
+ last_open && last_open.to_i < (Time.now.to_i - reenable_after)
23
+ end
24
+
25
+ def last_open
26
+ @last_open ||= redis.get(key)
27
+ end
28
+
29
+ def error
30
+ count = increment_rolling_window(key("error"))
31
+ if half_open? || should_open?(count)
32
+ open!
33
+ end
34
+ end
35
+
36
+ # generate a key to use in redis
37
+ def key(id=nil)
38
+ postfix = id ? "-#{id}" : ""
39
+ "cb2-#{service}#{postfix}"
40
+ end
41
+
42
+ protected
43
+
44
+ def increment_rolling_window(key)
22
45
  t = Time.now.to_i
23
46
  pipeline = redis.pipelined do
24
47
  # keep the sorted set clean
@@ -28,14 +51,10 @@ class CB2::RollingWindow
28
51
  # just count how many errors are left in the set
29
52
  redis.zcard(key)
30
53
  end
31
- if pipeline.last >= threshold
32
- open!
33
- end
54
+ return pipeline.last # return the count
34
55
  end
35
56
 
36
- private
37
-
38
- def cache_key
39
- "circuit-breaker-#{service}"
57
+ def should_open?(error_count)
58
+ error_count >= threshold
40
59
  end
41
60
  end
@@ -8,7 +8,4 @@ class CB2::Stub
8
8
  def open?
9
9
  !allow
10
10
  end
11
-
12
- def process
13
- end
14
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cb2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pedro Belo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-27 00:00:00.000000000 Z
11
+ date: 2014-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -38,6 +38,20 @@ dependencies:
38
38
  - - ! '>'
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rr
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.1'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -74,11 +88,12 @@ extra_rdoc_files: []
74
88
  files:
75
89
  - Gemfile
76
90
  - Gemfile.lock
77
- - lib/breaker.rb
78
91
  - lib/cb2.rb
79
- - lib/error.rb
80
- - lib/strategies/rolling_window.rb
81
- - lib/strategies/stub.rb
92
+ - lib/cb2/breaker.rb
93
+ - lib/cb2/error.rb
94
+ - lib/cb2/strategies/percentage.rb
95
+ - lib/cb2/strategies/rolling_window.rb
96
+ - lib/cb2/strategies/stub.rb
82
97
  homepage: http://github.com/pedro/cb2
83
98
  licenses: []
84
99
  metadata: {}