resilient 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/resilient/circuit_breaker.rb +37 -51
- data/lib/resilient/version.rb +1 -1
- metadata +13 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81aab488be171ccf0e6f8418c1d97e81b2fa708a
|
4
|
+
data.tar.gz: dffce71c386d7dae85c2f18a43985aad026c4402
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 082c69397be74dca6885167e4167822bcf4f0474e7945cf8bd95e3c687d624ed8905e4c048688230b014d72548da33625459be364ad82d79c71b8f02c21cd907
|
7
|
+
data.tar.gz: 1d25aeecb4829d3684309837d8c775bb21ded3f7952bed7c6e28277ff20be6988c2296211a2fb0ffa85ce5f51988fa522966c2389f22701b8f3602826d13eff5
|
data/README.md
CHANGED
@@ -63,7 +63,7 @@ circuit_breaker = Resilient::CircuitBreaker.new(properties: properties, key: Res
|
|
63
63
|
# etc etc etc
|
64
64
|
```
|
65
65
|
|
66
|
-
force the circuit to be always closed:
|
66
|
+
force the circuit to be always closed (great way to test in production with no impact, all instrumentation still runs which means you can measure in production with config and gain confidence while never actually opening a circuit incorrectly):
|
67
67
|
|
68
68
|
```ruby
|
69
69
|
properties = Resilient::CircuitBreaker::Properties.new(force_closed: true)
|
@@ -34,45 +34,27 @@ module Resilient
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def allow_request?
|
37
|
-
|
38
|
-
|
39
|
-
force_open: false,
|
40
|
-
force_closed: false,
|
41
|
-
}
|
42
|
-
|
43
|
-
instrument("resilient.circuit_breaker.allow_request", default_payload) { |payload|
|
44
|
-
result = if payload[:force_open] = @properties.force_open
|
37
|
+
instrument("resilient.circuit_breaker.allow_request", key: @key) { |payload|
|
38
|
+
payload[:result] = if payload[:force_open] = @properties.force_open
|
45
39
|
false
|
46
40
|
else
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
payload[:allow_single_request] = allow_single_request?
|
53
|
-
end
|
41
|
+
# we still want to simulate normal behavior/metrics like open, allow
|
42
|
+
# single request, etc. so it is possible to test properties in
|
43
|
+
# production without impact using force_closed so we run these here
|
44
|
+
# instead of in the else below
|
45
|
+
allow_request = !open? || allow_single_request?
|
54
46
|
|
47
|
+
if payload[:force_closed] = @properties.force_closed
|
55
48
|
true
|
56
49
|
else
|
57
|
-
|
58
|
-
true
|
59
|
-
else
|
60
|
-
payload[:allow_single_request] = allow_single_request?
|
61
|
-
end
|
50
|
+
allow_request
|
62
51
|
end
|
63
52
|
end
|
64
|
-
|
65
|
-
payload[:result] = result
|
66
53
|
}
|
67
54
|
end
|
68
55
|
|
69
56
|
def success
|
70
|
-
|
71
|
-
key: @key,
|
72
|
-
closed_the_circuit: false,
|
73
|
-
}
|
74
|
-
|
75
|
-
instrument("resilient.circuit_breaker.success", default_payload) { |payload|
|
57
|
+
instrument("resilient.circuit_breaker.success", key: @key) { |payload|
|
76
58
|
if @open
|
77
59
|
payload[:closed_the_circuit] = true
|
78
60
|
close_circuit
|
@@ -84,22 +66,14 @@ module Resilient
|
|
84
66
|
end
|
85
67
|
|
86
68
|
def failure
|
87
|
-
|
88
|
-
key: @key,
|
89
|
-
}
|
90
|
-
|
91
|
-
instrument("resilient.circuit_breaker.failure", default_payload) { |payload|
|
69
|
+
instrument("resilient.circuit_breaker.failure", key: @key) { |payload|
|
92
70
|
@metrics.failure
|
93
71
|
nil
|
94
72
|
}
|
95
73
|
end
|
96
74
|
|
97
75
|
def reset
|
98
|
-
|
99
|
-
key: @key,
|
100
|
-
}
|
101
|
-
|
102
|
-
instrument("resilient.circuit_breaker.reset", default_payload) { |payload|
|
76
|
+
instrument("resilient.circuit_breaker.reset", key: @key) { |payload|
|
103
77
|
@open = false
|
104
78
|
@opened_or_last_checked_at_epoch = 0
|
105
79
|
@metrics.reset
|
@@ -129,23 +103,35 @@ module Resilient
|
|
129
103
|
end
|
130
104
|
|
131
105
|
def open?
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
106
|
+
instrument("resilient.circuit_breaker.open") { |payload|
|
107
|
+
payload[:result] = if @open
|
108
|
+
true
|
109
|
+
else
|
110
|
+
if under_request_volume_threshold?
|
111
|
+
false
|
112
|
+
else
|
113
|
+
if under_error_threshold_percentage?
|
114
|
+
false
|
115
|
+
else
|
116
|
+
open_circuit
|
117
|
+
true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
}
|
138
122
|
end
|
139
123
|
|
140
124
|
def allow_single_request?
|
141
|
-
|
125
|
+
instrument("resilient.circuit_breaker.allow_single_request") { |payload|
|
126
|
+
now = Time.now.to_i
|
142
127
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
128
|
+
payload[:result] = if @open && now > (@opened_or_last_checked_at_epoch + @properties.sleep_window_seconds)
|
129
|
+
@opened_or_last_checked_at_epoch = now
|
130
|
+
true
|
131
|
+
else
|
132
|
+
false
|
133
|
+
end
|
134
|
+
}
|
149
135
|
end
|
150
136
|
|
151
137
|
def instrument(name, payload = {}, &block)
|
data/lib/resilient/version.rb
CHANGED
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resilient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Nunemaker
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.10'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.10'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: minitest
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '5.8'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '5.8'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: timecop
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 0.8.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 0.8.0
|
55
55
|
description:
|
@@ -59,8 +59,8 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
-
- .gitignore
|
63
|
-
- .travis.yml
|
62
|
+
- ".gitignore"
|
63
|
+
- ".travis.yml"
|
64
64
|
- Gemfile
|
65
65
|
- Guardfile
|
66
66
|
- LICENSE.txt
|
@@ -100,17 +100,17 @@ require_paths:
|
|
100
100
|
- lib
|
101
101
|
required_ruby_version: !ruby/object:Gem::Requirement
|
102
102
|
requirements:
|
103
|
-
- -
|
103
|
+
- - ">="
|
104
104
|
- !ruby/object:Gem::Version
|
105
105
|
version: '0'
|
106
106
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
requirements: []
|
112
112
|
rubyforge_project:
|
113
|
-
rubygems_version: 2.
|
113
|
+
rubygems_version: 2.2.2
|
114
114
|
signing_key:
|
115
115
|
specification_version: 4
|
116
116
|
summary: toolkit for resilient ruby apps
|