cb2 0.0.2 → 0.0.4
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 +5 -13
- data/Gemfile.lock +28 -18
- data/lib/cb2/breaker.rb +10 -2
- data/lib/cb2/strategies/percentage.rb +1 -1
- data/lib/cb2/strategies/rolling_window.rb +26 -13
- data/lib/cb2.rb +1 -0
- metadata +47 -27
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
ZDEzYjJjMTA5YTIxZDE2MDRkOWRiNzk0ZjQ3NDlkYzZhMmYwOTdiMA==
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a8af2405e21658d0d99e3d8b2a694e94c7e46201ec10bb738af3e78c50685668
|
4
|
+
data.tar.gz: 0cbdd27e23854ffbdfd5125c4dbbfcf8d6b546c5b4b07b964cdd7b5af1ff0d49
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
MjQyYjRlZTJhNDFiMDIzYzQxZjRjNTU4YTQzNDNjMzAzZTk1NzZhNmQ1MWZh
|
11
|
-
ZWI5MmFmN2MxMTEzOTczZWY0MGMwOWIwMzMyNWM0ZmJmNjgyYmQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MWQwYjA0Mzk1NTgxYWRiZmVkZmYwYzZlMDY5NTkwYTBlYWEzZDk5Mjc3ZTNl
|
14
|
-
MmE2ZjFmYTczODlmNjMyZWQyZTIyZmEyY2Y2OWNiMjU2MzczMDQ2MDBmYmYz
|
15
|
-
ZGRhZmNlMWNlMTkxZjQ2OGQyMjdlYjEzMzUzOGRjNWM2ZTU2NzE=
|
6
|
+
metadata.gz: e8ea4cbff5fc9a88d066f1fe551bd26ddbdaa93e0c7db04b4ca3dbcf8128520f4fc7e7e22a93c6e5878227b96c5483de60009453fc2124033485ea398f11c109
|
7
|
+
data.tar.gz: 793da2f7ddd54249515b66d619885c22f30eda34a2d6c1defb2749dd509c478d9ba3fc621be35968ea956067b9c6a60169250b39e6410d9b6442e82ab71896ea
|
data/Gemfile.lock
CHANGED
@@ -1,36 +1,46 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cb2 (0.0.
|
5
|
-
redis (~>
|
4
|
+
cb2 (0.0.4)
|
5
|
+
redis (~> 5, >= 4)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
connection_pool (2.4.1)
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
minitest (5.18.1)
|
13
|
+
rake (13.0.6)
|
14
|
+
redis (5.2.0)
|
15
|
+
redis-client (>= 0.22.0)
|
16
|
+
redis-client (0.22.2)
|
17
|
+
connection_pool
|
13
18
|
rr (1.1.2)
|
14
|
-
rspec (3.
|
15
|
-
rspec-core (~> 3.
|
16
|
-
rspec-expectations (~> 3.
|
17
|
-
rspec-mocks (~> 3.
|
18
|
-
rspec-core (3.
|
19
|
-
rspec-support (~> 3.
|
20
|
-
rspec-expectations (3.
|
19
|
+
rspec (3.12.0)
|
20
|
+
rspec-core (~> 3.12.0)
|
21
|
+
rspec-expectations (~> 3.12.0)
|
22
|
+
rspec-mocks (~> 3.12.0)
|
23
|
+
rspec-core (3.12.2)
|
24
|
+
rspec-support (~> 3.12.0)
|
25
|
+
rspec-expectations (3.12.3)
|
21
26
|
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
-
rspec-support (~> 3.
|
23
|
-
rspec-mocks (3.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
+
rspec-support (~> 3.12.0)
|
28
|
+
rspec-mocks (3.12.6)
|
29
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
+
rspec-support (~> 3.12.0)
|
31
|
+
rspec-support (3.12.1)
|
32
|
+
timecop (0.9.6)
|
27
33
|
|
28
34
|
PLATFORMS
|
29
35
|
ruby
|
30
36
|
|
31
37
|
DEPENDENCIES
|
32
38
|
cb2!
|
39
|
+
minitest (> 0)
|
33
40
|
rake (> 0)
|
34
41
|
rr (~> 1.1)
|
35
42
|
rspec (~> 3.1)
|
36
|
-
timecop (
|
43
|
+
timecop (> 0)
|
44
|
+
|
45
|
+
BUNDLED WITH
|
46
|
+
2.3.26
|
data/lib/cb2/breaker.rb
CHANGED
@@ -8,16 +8,19 @@ class CB2::Breaker
|
|
8
8
|
|
9
9
|
def run
|
10
10
|
if open?
|
11
|
-
raise CB2::BreakerOpen
|
11
|
+
raise CB2::BreakerOpen.new("#{service} breaker open")
|
12
12
|
end
|
13
13
|
|
14
14
|
begin
|
15
15
|
process_count
|
16
|
-
yield
|
16
|
+
ret = yield
|
17
|
+
process_success
|
17
18
|
rescue => e
|
18
19
|
process_error
|
19
20
|
raise e
|
20
21
|
end
|
22
|
+
|
23
|
+
return ret
|
21
24
|
end
|
22
25
|
|
23
26
|
def open?
|
@@ -31,6 +34,11 @@ class CB2::Breaker
|
|
31
34
|
rescue Redis::BaseError
|
32
35
|
end
|
33
36
|
|
37
|
+
def process_success
|
38
|
+
strategy.success if strategy.respond_to?(:success)
|
39
|
+
rescue Redis::BaseError
|
40
|
+
end
|
41
|
+
|
34
42
|
def process_error
|
35
43
|
strategy.error if strategy.respond_to?(:error)
|
36
44
|
rescue Redis::BaseError
|
@@ -6,18 +6,14 @@ 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 = options[:redis] || Redis.
|
9
|
+
@redis = options[:redis] || Redis.new
|
10
10
|
end
|
11
11
|
|
12
12
|
def open?
|
13
|
+
@last_open = nil # always fetch the latest value from redis here
|
13
14
|
last_open && last_open.to_i > (Time.now.to_i - reenable_after)
|
14
15
|
end
|
15
16
|
|
16
|
-
def open!
|
17
|
-
@last_open = Time.now.to_i
|
18
|
-
redis.set(key, @last_open)
|
19
|
-
end
|
20
|
-
|
21
17
|
def half_open?
|
22
18
|
last_open && last_open.to_i < (Time.now.to_i - reenable_after)
|
23
19
|
end
|
@@ -26,13 +22,29 @@ class CB2::RollingWindow
|
|
26
22
|
@last_open ||= redis.get(key)
|
27
23
|
end
|
28
24
|
|
25
|
+
def success
|
26
|
+
if half_open?
|
27
|
+
reset!
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
29
31
|
def error
|
30
32
|
count = increment_rolling_window(key("error"))
|
31
33
|
if half_open? || should_open?(count)
|
32
|
-
|
34
|
+
trip!
|
33
35
|
end
|
34
36
|
end
|
35
37
|
|
38
|
+
def reset!
|
39
|
+
@last_open = nil
|
40
|
+
redis.del(key)
|
41
|
+
end
|
42
|
+
|
43
|
+
def trip!
|
44
|
+
@last_open = Time.now.to_i
|
45
|
+
redis.set(key, @last_open)
|
46
|
+
end
|
47
|
+
|
36
48
|
# generate a key to use in redis
|
37
49
|
def key(id=nil)
|
38
50
|
postfix = id ? "-#{id}" : ""
|
@@ -42,16 +54,17 @@ class CB2::RollingWindow
|
|
42
54
|
protected
|
43
55
|
|
44
56
|
def increment_rolling_window(key)
|
45
|
-
t
|
46
|
-
|
57
|
+
t = Time.now.to_i
|
58
|
+
result = redis.pipelined do |pipeline|
|
47
59
|
# keep the sorted set clean
|
48
|
-
|
60
|
+
pipeline.zremrangebyscore(key, "-inf", t - duration)
|
49
61
|
# add as a random uuid because sorted sets won't take duplicate items:
|
50
|
-
|
62
|
+
pipeline.zadd(key, t, SecureRandom.uuid)
|
51
63
|
# just count how many errors are left in the set
|
52
|
-
|
64
|
+
pipeline.zcard(key)
|
53
65
|
end
|
54
|
-
|
66
|
+
|
67
|
+
result.last # return the count
|
55
68
|
end
|
56
69
|
|
57
70
|
def should_open?(error_count)
|
data/lib/cb2.rb
CHANGED
metadata
CHANGED
@@ -1,87 +1,108 @@
|
|
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.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pedro Belo
|
8
|
-
|
8
|
+
- Matt Rohrer
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2024-05-22 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: redis
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - ~>
|
18
|
+
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
+
version: '5'
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '4'
|
20
24
|
type: :runtime
|
21
25
|
prerelease: false
|
22
26
|
version_requirements: !ruby/object:Gem::Requirement
|
23
27
|
requirements:
|
24
|
-
- - ~>
|
28
|
+
- - "~>"
|
25
29
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
30
|
+
version: '5'
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4'
|
27
34
|
- !ruby/object:Gem::Dependency
|
28
35
|
name: rake
|
29
36
|
requirement: !ruby/object:Gem::Requirement
|
30
37
|
requirements:
|
31
|
-
- -
|
38
|
+
- - ">"
|
32
39
|
- !ruby/object:Gem::Version
|
33
40
|
version: '0'
|
34
41
|
type: :development
|
35
42
|
prerelease: false
|
36
43
|
version_requirements: !ruby/object:Gem::Requirement
|
37
44
|
requirements:
|
38
|
-
- -
|
45
|
+
- - ">"
|
39
46
|
- !ruby/object:Gem::Version
|
40
47
|
version: '0'
|
41
48
|
- !ruby/object:Gem::Dependency
|
42
49
|
name: rr
|
43
50
|
requirement: !ruby/object:Gem::Requirement
|
44
51
|
requirements:
|
45
|
-
- - ~>
|
52
|
+
- - "~>"
|
46
53
|
- !ruby/object:Gem::Version
|
47
54
|
version: '1.1'
|
48
55
|
type: :development
|
49
56
|
prerelease: false
|
50
57
|
version_requirements: !ruby/object:Gem::Requirement
|
51
58
|
requirements:
|
52
|
-
- - ~>
|
59
|
+
- - "~>"
|
53
60
|
- !ruby/object:Gem::Version
|
54
61
|
version: '1.1'
|
55
62
|
- !ruby/object:Gem::Dependency
|
56
63
|
name: rspec
|
57
64
|
requirement: !ruby/object:Gem::Requirement
|
58
65
|
requirements:
|
59
|
-
- - ~>
|
66
|
+
- - "~>"
|
60
67
|
- !ruby/object:Gem::Version
|
61
68
|
version: '3.1'
|
62
69
|
type: :development
|
63
70
|
prerelease: false
|
64
71
|
version_requirements: !ruby/object:Gem::Requirement
|
65
72
|
requirements:
|
66
|
-
- - ~>
|
73
|
+
- - "~>"
|
67
74
|
- !ruby/object:Gem::Version
|
68
75
|
version: '3.1'
|
76
|
+
- !ruby/object:Gem::Dependency
|
77
|
+
name: minitest
|
78
|
+
requirement: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
69
90
|
- !ruby/object:Gem::Dependency
|
70
91
|
name: timecop
|
71
92
|
requirement: !ruby/object:Gem::Requirement
|
72
93
|
requirements:
|
73
|
-
- -
|
94
|
+
- - ">"
|
74
95
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0
|
96
|
+
version: '0'
|
76
97
|
type: :development
|
77
98
|
prerelease: false
|
78
99
|
version_requirements: !ruby/object:Gem::Requirement
|
79
100
|
requirements:
|
80
|
-
- -
|
101
|
+
- - ">"
|
81
102
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0
|
103
|
+
version: '0'
|
83
104
|
description: Implementation of the circuit breaker pattern in Ruby
|
84
|
-
email:
|
105
|
+
email: matt@prognostikos.com
|
85
106
|
executables: []
|
86
107
|
extensions: []
|
87
108
|
extra_rdoc_files: []
|
@@ -94,28 +115,27 @@ files:
|
|
94
115
|
- lib/cb2/strategies/percentage.rb
|
95
116
|
- lib/cb2/strategies/rolling_window.rb
|
96
117
|
- lib/cb2/strategies/stub.rb
|
97
|
-
homepage: http://github.com/
|
98
|
-
licenses:
|
118
|
+
homepage: http://github.com/prognostikos/cb2
|
119
|
+
licenses:
|
120
|
+
- MIT
|
99
121
|
metadata: {}
|
100
|
-
post_install_message:
|
122
|
+
post_install_message:
|
101
123
|
rdoc_options: []
|
102
124
|
require_paths:
|
103
125
|
- lib
|
104
126
|
required_ruby_version: !ruby/object:Gem::Requirement
|
105
127
|
requirements:
|
106
|
-
- -
|
128
|
+
- - ">="
|
107
129
|
- !ruby/object:Gem::Version
|
108
130
|
version: '0'
|
109
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
132
|
requirements:
|
111
|
-
- -
|
133
|
+
- - ">="
|
112
134
|
- !ruby/object:Gem::Version
|
113
135
|
version: '0'
|
114
136
|
requirements: []
|
115
|
-
|
116
|
-
|
117
|
-
signing_key:
|
137
|
+
rubygems_version: 3.5.6
|
138
|
+
signing_key:
|
118
139
|
specification_version: 4
|
119
140
|
summary: Circuit breaker
|
120
141
|
test_files: []
|
121
|
-
has_rdoc:
|