sidekiq-circuit-breaker 0.1.4 → 0.1.5
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/CHANGELOG.md +6 -0
- data/Gemfile.lock +1 -1
- data/lib/sidekiq/circuit_breaker.rb +2 -1
- data/lib/sidekiq/circuit_breaker/api.rb +13 -2
- data/lib/sidekiq/circuit_breaker/manager.rb +3 -3
- data/lib/sidekiq/circuit_breaker/middleware.rb +2 -91
- data/lib/sidekiq/circuit_breaker/middleware/client.rb +51 -0
- data/lib/sidekiq/circuit_breaker/middleware/server.rb +39 -0
- data/lib/sidekiq/circuit_breaker/scope.rb +18 -0
- data/lib/sidekiq/circuit_breaker/version.rb +1 -1
- data/lib/sidekiq/circuit_breaker/worker.rb +0 -22
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e51ce2527ccdcb2cf1081f47c5e37fffed8043a264c9749dcbe6d1d6ec409e44
|
4
|
+
data.tar.gz: eb6f8fbd9e30cc88c18b82aa51a8474d71dbcc3ef461e5470934010371ae1c67
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42befd4cf2b41db3690590426eefeba7548fed8cc4aab59af943eec1fb4ab75454a8cbc0496e9e6178c9e3b1add247296505367ce9c2bed90aa634d7f06d27a7
|
7
|
+
data.tar.gz: 1efbecc602fcebbeaa07481e2e92599ad990ef44130f7528edc30d60801c2bfac41aa3c8dcbe59c0b9a035e8cbfb220c32e2fcaa3dc7cd9fceab62ce0ad2d064
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
@@ -15,6 +15,17 @@ module Sidekiq
|
|
15
15
|
true
|
16
16
|
end
|
17
17
|
|
18
|
+
def close_circuit(scope)
|
19
|
+
raise ArgumentError, 'scope must not be nil' if scope.nil?
|
20
|
+
Sidekiq.redis do |conn|
|
21
|
+
conn.del(open_key(scope))
|
22
|
+
# reset failure count
|
23
|
+
conn.del(failure_key(scope))
|
24
|
+
end
|
25
|
+
true
|
26
|
+
|
27
|
+
end
|
28
|
+
|
18
29
|
def register_failure_for_scope(scope, ttl = 120)
|
19
30
|
raise ArgumentError, 'scope must not be nil' if scope.nil?
|
20
31
|
key = failure_key(scope)
|
@@ -36,13 +47,13 @@ module Sidekiq
|
|
36
47
|
end
|
37
48
|
end
|
38
49
|
|
39
|
-
def
|
50
|
+
def time_to_close_the_circuit(scope)
|
40
51
|
Sidekiq.redis do |conn|
|
41
52
|
conn.ttl(open_key(scope))
|
42
53
|
end
|
43
54
|
end
|
44
55
|
|
45
|
-
def
|
56
|
+
def circuit_open?(scope)
|
46
57
|
Sidekiq.redis do |conn|
|
47
58
|
conn.exists(open_key(scope))
|
48
59
|
end
|
@@ -15,7 +15,7 @@ module Sidekiq
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def open?
|
18
|
-
|
18
|
+
circuit_open?(@scope)
|
19
19
|
end
|
20
20
|
|
21
21
|
def closed?
|
@@ -30,8 +30,8 @@ module Sidekiq
|
|
30
30
|
open_circuit(@scope, @options.max_open_time)
|
31
31
|
end
|
32
32
|
|
33
|
-
def
|
34
|
-
|
33
|
+
def time_to_close
|
34
|
+
time_to_close_the_circuit(@scope)
|
35
35
|
end
|
36
36
|
|
37
37
|
def register_failure
|
@@ -1,94 +1,5 @@
|
|
1
|
-
require 'sidekiq/circuit_breaker/
|
2
|
-
require 'sidekiq/circuit_breaker/middleware'
|
3
|
-
require 'sidekiq/client'
|
4
|
-
|
5
|
-
module Sidekiq
|
6
|
-
module CircuitBreaker
|
7
|
-
module Middleware
|
8
|
-
class Client
|
9
|
-
def call(worker_class, msg, queue, redis_pool)
|
10
|
-
begin
|
11
|
-
worker = constantize(worker_class)
|
12
|
-
rescue NameError
|
13
|
-
return yield
|
14
|
-
end
|
15
|
-
|
16
|
-
circuit_breaker = worker.respond_to?(:sidekiq_circuit_breaker_enabled?)
|
17
|
-
return yield unless circuit_breaker
|
18
|
-
|
19
|
-
options = worker.sidekiq_circuit_breaker_options
|
20
|
-
scope = extract_scope(options, msg) || worker_class
|
21
|
-
|
22
|
-
mgr = CircuitBreaker::Manager.new(scope, options)
|
23
|
-
if mgr.open? && msg['at'].nil?
|
24
|
-
msg['at'] = (Time.now + (mgr.time_to_open + additional_seconds)).to_f
|
25
|
-
end
|
26
|
-
|
27
|
-
yield
|
28
|
-
end
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
|
-
def additional_seconds
|
33
|
-
rand(3..10)
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def extract_scope(options, msg)
|
39
|
-
scope = options.scope
|
40
|
-
return scope if scope.is_a?(String)
|
41
|
-
return unless scope.respond_to?(:call)
|
42
|
-
|
43
|
-
options.scope.call(*msg['args'])
|
44
|
-
end
|
45
|
-
|
46
|
-
def constantize(str)
|
47
|
-
names = str.split('::')
|
48
|
-
names.shift if names.empty? || names.first.empty?
|
49
|
-
|
50
|
-
names.inject(Object) do |constant, name|
|
51
|
-
constant.const_defined?(name, false) ? constant.const_get(name, false) : constant.const_missing(name)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
class Server
|
57
|
-
def call(worker, msg, queue)
|
58
|
-
circuit_breaker_enabled = worker.class.respond_to?(:sidekiq_circuit_breaker_enabled?)
|
59
|
-
return yield unless circuit_breaker_enabled
|
60
|
-
|
61
|
-
def worker.perform(*args)
|
62
|
-
manager = sidekiq_circuit_breaker_manager(args)
|
63
|
-
|
64
|
-
if manager.open?
|
65
|
-
begin
|
66
|
-
Sidekiq::Client.push(
|
67
|
-
'class' => self.class,
|
68
|
-
'args' => args
|
69
|
-
)
|
70
|
-
return
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
super(*args)
|
75
|
-
end
|
76
|
-
|
77
|
-
manager = worker.sidekiq_circuit_breaker_manager(msg['args'])
|
78
|
-
|
79
|
-
begin
|
80
|
-
yield
|
81
|
-
rescue => e
|
82
|
-
manager.evaluate_failure
|
83
|
-
raise e
|
84
|
-
end
|
85
|
-
|
86
|
-
manager.register_success
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
1
|
+
require 'sidekiq/circuit_breaker/middleware/client'
|
2
|
+
require 'sidekiq/circuit_breaker/middleware/server'
|
92
3
|
|
93
4
|
Sidekiq.configure_client do |config|
|
94
5
|
config.client_middleware do |chain|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'sidekiq/client'
|
2
|
+
require 'sidekiq/circuit_breaker/manager'
|
3
|
+
require 'sidekiq/circuit_breaker/scope'
|
4
|
+
|
5
|
+
module Sidekiq
|
6
|
+
module CircuitBreaker
|
7
|
+
module Middleware
|
8
|
+
class Client
|
9
|
+
include Sidekiq::CircuitBreaker::Scope
|
10
|
+
|
11
|
+
def call(worker_class, msg, queue, redis_pool)
|
12
|
+
begin
|
13
|
+
worker = constantize(worker_class)
|
14
|
+
rescue NameError
|
15
|
+
return yield
|
16
|
+
end
|
17
|
+
|
18
|
+
circuit_breaker = worker.respond_to?(:sidekiq_circuit_breaker_enabled?)
|
19
|
+
return yield unless circuit_breaker
|
20
|
+
|
21
|
+
options = worker.sidekiq_circuit_breaker_options
|
22
|
+
scope = extract_scope(worker_class, msg, options)
|
23
|
+
|
24
|
+
mgr = CircuitBreaker::Manager.new(scope, options)
|
25
|
+
if mgr.open? && msg['at'].nil?
|
26
|
+
msg['at'] = (Time.now + (mgr.time_to_close + additional_seconds)).to_f
|
27
|
+
end
|
28
|
+
|
29
|
+
yield
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def additional_seconds
|
35
|
+
rand(3..10)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def constantize(str)
|
41
|
+
names = str.split('::')
|
42
|
+
names.shift if names.empty? || names.first.empty?
|
43
|
+
|
44
|
+
names.inject(Object) do |constant, name|
|
45
|
+
constant.const_defined?(name, false) ? constant.const_get(name, false) : constant.const_missing(name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'sidekiq/circuit_breaker/scope'
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module CircuitBreaker
|
5
|
+
module Middleware
|
6
|
+
class Server
|
7
|
+
include Sidekiq::CircuitBreaker::Scope
|
8
|
+
|
9
|
+
def call(worker, msg, queue)
|
10
|
+
circuit_breaker_enabled = worker.class.respond_to?(:sidekiq_circuit_breaker_enabled?)
|
11
|
+
return yield unless circuit_breaker_enabled
|
12
|
+
|
13
|
+
options = worker.class.sidekiq_circuit_breaker_options
|
14
|
+
scope = extract_scope(worker.class.name, msg, options)
|
15
|
+
manager = Manager.new(scope, options)
|
16
|
+
resquedule_job(worker, msg) and return if manager.open?
|
17
|
+
|
18
|
+
begin
|
19
|
+
yield
|
20
|
+
rescue => e
|
21
|
+
manager.evaluate_failure
|
22
|
+
raise e
|
23
|
+
end
|
24
|
+
|
25
|
+
manager.register_success
|
26
|
+
end
|
27
|
+
|
28
|
+
def resquedule_job(worker, msg)
|
29
|
+
Sidekiq::Client.push(
|
30
|
+
'class' => worker.class.name,
|
31
|
+
'args' => msg['args']
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module CircuitBreaker
|
3
|
+
module Scope
|
4
|
+
def extract_scope(worker_class_name, msg, options)
|
5
|
+
from_setup =
|
6
|
+
begin
|
7
|
+
scope = options.scope
|
8
|
+
return scope if scope.is_a?(String)
|
9
|
+
return unless scope.respond_to?(:call)
|
10
|
+
|
11
|
+
options.scope.call(*msg['args'])
|
12
|
+
end
|
13
|
+
|
14
|
+
from_setup || worker_class_name
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -7,28 +7,6 @@ module Sidekiq
|
|
7
7
|
base.extend(ClassMethods)
|
8
8
|
end
|
9
9
|
|
10
|
-
def sidekiq_circuit_breaker_manager(args)
|
11
|
-
options = self.class.sidekiq_circuit_breaker_options
|
12
|
-
scope = scope(args)
|
13
|
-
CircuitBreaker::Manager.new(scope, options)
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def scope(args)
|
19
|
-
options = self.class.sidekiq_circuit_breaker_options
|
20
|
-
extract_scope(options, args) || self.class.name
|
21
|
-
end
|
22
|
-
|
23
|
-
def extract_scope(options, args)
|
24
|
-
scope = options.scope
|
25
|
-
return scope if scope.is_a?(String)
|
26
|
-
return unless scope.respond_to?(:call)
|
27
|
-
|
28
|
-
options.scope.call(*args)
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
10
|
module ClassMethods
|
33
11
|
def sidekiq_circuit_breaker_enabled?
|
34
12
|
true
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sidekiq-circuit-breaker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Sousa
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sidekiq
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- ".gitignore"
|
77
77
|
- ".rspec"
|
78
78
|
- ".travis.yml"
|
79
|
+
- CHANGELOG.md
|
79
80
|
- Gemfile
|
80
81
|
- Gemfile.lock
|
81
82
|
- LICENSE.txt
|
@@ -88,6 +89,9 @@ files:
|
|
88
89
|
- lib/sidekiq/circuit_breaker/configuration.rb
|
89
90
|
- lib/sidekiq/circuit_breaker/manager.rb
|
90
91
|
- lib/sidekiq/circuit_breaker/middleware.rb
|
92
|
+
- lib/sidekiq/circuit_breaker/middleware/client.rb
|
93
|
+
- lib/sidekiq/circuit_breaker/middleware/server.rb
|
94
|
+
- lib/sidekiq/circuit_breaker/scope.rb
|
91
95
|
- lib/sidekiq/circuit_breaker/version.rb
|
92
96
|
- lib/sidekiq/circuit_breaker/worker.rb
|
93
97
|
- sidekiq-circuit-breaker.gemspec
|