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 +8 -8
- data/Gemfile.lock +3 -1
- data/lib/cb2.rb +5 -4
- data/lib/{breaker.rb → cb2/breaker.rb} +20 -5
- data/lib/{error.rb → cb2/error.rb} +0 -0
- data/lib/cb2/strategies/percentage.rb +16 -0
- data/lib/{strategies → cb2/strategies}/rolling_window.rb +31 -12
- data/lib/{strategies → cb2/strategies}/stub.rb +0 -3
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTE5OWQ3ZDliNTg4OGUyNjU4YTNiOGVkM2FjNzAwM2VkMTdiZWU4Zg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDEzYjJjMTA5YTIxZDE2MDRkOWRiNzk0ZjQ3NDlkYzZhMmYwOTdiMA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YTg1OGMwZjYzYTk5NTQ0NTQ4MDY2M2ZmNGZmOGZjZGQ4NmNjNmYwNGE4ZWRh
|
10
|
+
MjQyYjRlZTJhNDFiMDIzYzQxZjRjNTU4YTQzNDNjMzAzZTk1NzZhNmQ1MWZh
|
11
|
+
ZWI5MmFmN2MxMTEzOTczZWY0MGMwOWIwMzMyNWM0ZmJmNjgyYmQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
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.
|
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/
|
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
|
-
|
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
|
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
|
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
|
-
|
13
|
+
last_open && last_open.to_i > (Time.now.to_i - reenable_after)
|
14
14
|
end
|
15
15
|
|
16
16
|
def open!
|
17
|
-
|
17
|
+
@last_open = Time.now.to_i
|
18
|
+
redis.set(key, @last_open)
|
18
19
|
end
|
19
20
|
|
20
|
-
def
|
21
|
-
|
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
|
-
|
32
|
-
open!
|
33
|
-
end
|
54
|
+
return pipeline.last # return the count
|
34
55
|
end
|
35
56
|
|
36
|
-
|
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
|
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.
|
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-
|
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/
|
80
|
-
- lib/
|
81
|
-
- lib/strategies/
|
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: {}
|