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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzM2YWYxM2YyMmMxMmQ4NWZkNjczYjM5OGQ3NDBlZTk4MjViODdlNw==
4
+ ZTE5OWQ3ZDliNTg4OGUyNjU4YTNiOGVkM2FjNzAwM2VkMTdiZWU4Zg==
5
5
  data.tar.gz: !binary |-
6
- YTcwMzhiMTAyMDk0Mjc5YzZkMWM0MzBmYmQ2OTM2ZGQ2NDJhMTE5OA==
6
+ ZDEzYjJjMTA5YTIxZDE2MDRkOWRiNzk0ZjQ3NDlkYzZhMmYwOTdiMA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MjYzYzVhNTFhNWJiMDgyMTBhZTMzYTg1Mjk5ZGFkZDRkMzM4MTY2YjdhMGI0
10
- YjY2MTJhMDY0MzdkZjAyZTk2M2MxYWFjMTc5OTIyZWY0YjVhYWVmYmU1MmM0
11
- ZDNhNWI4NWEwOGVhYmIyNTVmNmZlMDNhMjQwNmU0MTViNzAwMzE=
9
+ YTg1OGMwZjYzYTk5NTQ0NTQ4MDY2M2ZmNGZmOGZjZGQ4NmNjNmYwNGE4ZWRh
10
+ MjQyYjRlZTJhNDFiMDIzYzQxZjRjNTU4YTQzNDNjMzAzZTk1NzZhNmQ1MWZh
11
+ ZWI5MmFmN2MxMTEzOTczZWY0MGMwOWIwMzMyNWM0ZmJmNjgyYmQ=
12
12
  data.tar.gz: !binary |-
13
- NjY4OWQxMGZhYjI5OWFhYTk2ZWJkZGU4NDgwNTJiMDIyNjRmMmQ3OTk1OTRk
14
- ZTcwNjhiM2UxNzEzNzQ2MGFlZDZjNTQ0ZjkwOGUxZjEwYzYzMTgzYzkyNjE4
15
- N2UxZTU1ZTBlOGJhZjU4MWEzMzcxZTIwMzllMmFlMjRiMDYwNzQ=
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.1)
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/stub"
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
- strategy.process
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 nil, :rolling_window
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 nil, :stub
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
- redis.exists(cache_key)
13
+ last_open && last_open.to_i > (Time.now.to_i - reenable_after)
14
14
  end
15
15
 
16
16
  def open!
17
- redis.setex(cache_key, reenable_after, 1)
17
+ @last_open = Time.now.to_i
18
+ redis.set(key, @last_open)
18
19
  end
19
20
 
20
- def process
21
- key = "circuit-breaker-count-#{service}"
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
- if pipeline.last >= threshold
32
- open!
33
- end
54
+ return pipeline.last # return the count
34
55
  end
35
56
 
36
- private
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
@@ -8,7 +8,4 @@ class CB2::Stub
8
8
  def open?
9
9
  !allow
10
10
  end
11
-
12
- def process
13
- end
14
11
  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.1
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-27 00:00:00.000000000 Z
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/error.rb
80
- - lib/strategies/rolling_window.rb
81
- - lib/strategies/stub.rb
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: {}