circuit_breakage 0.1.1 → 0.1.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 +4 -4
- data/README.md +6 -5
- data/lib/circuit_breakage/redis_backed_breaker.rb +18 -9
- data/lib/circuit_breakage/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9026fcf0d50eb38007dd97047ae181393d29a68b
|
4
|
+
data.tar.gz: ab1c9b2050bb6e6293e3347ce40fe5588ccbe179
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7627acaac4f74fd5988531384648f43a35d27a3029e1342ea1b140a57a22f7dd31322162b918d8c5339d9ef655118c62020eed1f9c476dd2ed4f9aedbb759c02
|
7
|
+
data.tar.gz: c27a067b42074c300fbd4fc94e8f3d77d4f0a9ef7dc5bf2b4a4df5e66e646eea108a27920f9e8d18891f9c9b89f84df81de095f81a41b89ea2f24c261cf09c23
|
data/README.md
CHANGED
@@ -33,7 +33,12 @@ end
|
|
33
33
|
The unique feature of this particular Circuit Breaker gem is that it also
|
34
34
|
supports shared state via Redis, using the SETNX and GETSET commands. This
|
35
35
|
allows a number of circuit breakers running in separate processes to trip and
|
36
|
-
un-trip in unison.
|
36
|
+
un-trip in unison. To be specific, when the circuit is closed, all processes
|
37
|
+
proceed as normal. When the circuit is open, all processes will raise
|
38
|
+
`CircuitBreakage::CircuitOpen`. When the circuit is open, but the retry
|
39
|
+
duration has expired (this is sometimes referred to as a "half open" state),
|
40
|
+
exactly *one* process will retry, and then either close the circuit or reset
|
41
|
+
the retry timer as appropriate.
|
37
42
|
|
38
43
|
```ruby
|
39
44
|
connection = some_redis_connection
|
@@ -42,7 +47,3 @@ key = 'my_app/some_operation'
|
|
42
47
|
breaker = CircuitBreakage::RedisBackedBreaker.new(connection, key, block)
|
43
48
|
# Everything else is the same as above.
|
44
49
|
```
|
45
|
-
|
46
|
-
So, if you have the same piece of code running on 27 instances across 3
|
47
|
-
different servers, as soon as one trips, they all trip, and as soon as one
|
48
|
-
resets, they all reset.
|
@@ -6,13 +6,14 @@ module CircuitBreakage
|
|
6
6
|
class RedisBackedBreaker < Breaker
|
7
7
|
|
8
8
|
# How long before we decide a lock-holder has crashed, in seconds.
|
9
|
-
|
9
|
+
DEFAULT_LOCK_TIMEOUT = DEFAULT_TIMEOUT + 10
|
10
10
|
|
11
|
-
attr_reader :connection, :key
|
11
|
+
attr_reader :connection, :key, :lock_timeout
|
12
12
|
|
13
13
|
def initialize(connection, key, block)
|
14
14
|
@connection = connection
|
15
15
|
@key = key
|
16
|
+
@lock_timeout = DEFAULT_LOCK_TIMEOUT
|
16
17
|
super(block)
|
17
18
|
end
|
18
19
|
|
@@ -38,22 +39,30 @@ module CircuitBreakage
|
|
38
39
|
|
39
40
|
def try_with_mutex(lock, &block)
|
40
41
|
mutex_key = "#{@key}/locks/#{lock}"
|
42
|
+
lock_timestamp = Time.now.to_i
|
41
43
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
# See http://redis.io/commands/setnx for a walkthrough of this logic.
|
45
|
+
acquired = @connection.setnx(mutex_key, lock_timestamp)
|
46
|
+
if !acquired
|
47
|
+
locked_at = @connection.get(mutex_key).to_i
|
48
|
+
raise CircuitBreakage::CircuitOpen if !lock_expired(locked_at)
|
49
|
+
locked_at_second_check = @connection.getset(mutex_key, Time.now.to_i).to_i
|
47
50
|
raise CircuitBreakage::CircuitOpen if locked_at_second_check != locked_at
|
48
|
-
# If we get here, then the lock is expired, and we're the first to re-acquire it.
|
49
51
|
end
|
50
52
|
|
51
53
|
begin
|
52
54
|
block.call
|
53
55
|
ensure
|
54
|
-
|
56
|
+
if !lock_expired(lock_timestamp)
|
57
|
+
# There's a tiny unavoidable race condition here.
|
58
|
+
@connection.del(mutex_key)
|
59
|
+
end
|
55
60
|
end
|
56
61
|
end
|
57
62
|
|
63
|
+
def lock_expired(timestamp)
|
64
|
+
timestamp + @lock_timeout < Time.now.to_i
|
65
|
+
end
|
66
|
+
|
58
67
|
end
|
59
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: circuit_breakage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Hyland
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|