cb2 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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: {}
|