cb2 0.0.1

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.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YzM2YWYxM2YyMmMxMmQ4NWZkNjczYjM5OGQ3NDBlZTk4MjViODdlNw==
5
+ data.tar.gz: !binary |-
6
+ YTcwMzhiMTAyMDk0Mjc5YzZkMWM0MzBmYmQ2OTM2ZGQ2NDJhMTE5OA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ MjYzYzVhNTFhNWJiMDgyMTBhZTMzYTg1Mjk5ZGFkZDRkMzM4MTY2YjdhMGI0
10
+ YjY2MTJhMDY0MzdkZjAyZTk2M2MxYWFjMTc5OTIyZWY0YjVhYWVmYmU1MmM0
11
+ ZDNhNWI4NWEwOGVhYmIyNTVmNmZlMDNhMjQwNmU0MTViNzAwMzE=
12
+ data.tar.gz: !binary |-
13
+ NjY4OWQxMGZhYjI5OWFhYTk2ZWJkZGU4NDgwNTJiMDIyNjRmMmQ3OTk1OTRk
14
+ ZTcwNjhiM2UxNzEzNzQ2MGFlZDZjNTQ0ZjkwOGUxZjEwYzYzMTgzYzkyNjE4
15
+ N2UxZTU1ZTBlOGJhZjU4MWEzMzcxZTIwMzllMmFlMjRiMDYwNzQ=
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,34 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cb2 (0.0.1)
5
+ redis (~> 3.1)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.2.5)
11
+ rake (10.3.2)
12
+ redis (3.1.0)
13
+ rspec (3.1.0)
14
+ rspec-core (~> 3.1.0)
15
+ rspec-expectations (~> 3.1.0)
16
+ rspec-mocks (~> 3.1.0)
17
+ rspec-core (3.1.7)
18
+ rspec-support (~> 3.1.0)
19
+ rspec-expectations (3.1.2)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.1.0)
22
+ rspec-mocks (3.1.3)
23
+ rspec-support (~> 3.1.0)
24
+ rspec-support (3.1.2)
25
+ timecop (0.7.1)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ cb2!
32
+ rake (> 0)
33
+ rspec (~> 3.1)
34
+ timecop (~> 0.7)
@@ -0,0 +1,40 @@
1
+ class CB2::Breaker
2
+ attr_accessor :service, :strategy
3
+
4
+ def initialize(options)
5
+ @service = options[:service] || "default"
6
+ @strategy = initialize_strategy(options)
7
+ end
8
+
9
+ def run
10
+ if open?
11
+ raise CB2::BreakerOpen
12
+ end
13
+
14
+ begin
15
+ yield
16
+ rescue => e
17
+ strategy.process
18
+ raise e
19
+ end
20
+ end
21
+
22
+ def open?
23
+ strategy.open?
24
+ end
25
+
26
+ def initialize_strategy(options)
27
+ strategy_options = options.dup.merge(service: self.service)
28
+
29
+ if options[:strategy].respond_to?(:open)
30
+ return options[:strategy].new(strategy_options)
31
+ end
32
+
33
+ case options[:strategy]
34
+ when nil, :rolling_window
35
+ CB2::RollingWindow.new(strategy_options)
36
+ when nil, :stub
37
+ CB2::Stub.new(strategy_options)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ require "redis"
2
+
3
+ module CB2
4
+ end
5
+
6
+ require "breaker"
7
+ require "error"
8
+ require "strategies/rolling_window"
9
+ require "strategies/stub"
@@ -0,0 +1,4 @@
1
+ module CB2
2
+ class BreakerOpen < StandardError
3
+ end
4
+ end
@@ -0,0 +1,41 @@
1
+ class CB2::RollingWindow
2
+ attr_accessor :service, :duration, :threshold, :reenable_after, :redis
3
+
4
+ def initialize(options)
5
+ @service = options.fetch(:service)
6
+ @duration = options.fetch(:duration)
7
+ @threshold = options.fetch(:threshold)
8
+ @reenable_after = options.fetch(:reenable_after)
9
+ @redis = Redis.current
10
+ end
11
+
12
+ def open?
13
+ redis.exists(cache_key)
14
+ end
15
+
16
+ def open!
17
+ redis.setex(cache_key, reenable_after, 1)
18
+ end
19
+
20
+ def process
21
+ key = "circuit-breaker-count-#{service}"
22
+ t = Time.now.to_i
23
+ pipeline = redis.pipelined do
24
+ # keep the sorted set clean
25
+ redis.zremrangebyscore(key, "-inf", t - duration)
26
+ # add as a random uuid because sorted sets won't take duplicate items:
27
+ redis.zadd(key, t, SecureRandom.uuid)
28
+ # just count how many errors are left in the set
29
+ redis.zcard(key)
30
+ end
31
+ if pipeline.last >= threshold
32
+ open!
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def cache_key
39
+ "circuit-breaker-#{service}"
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ class CB2::Stub
2
+ attr_accessor :allow
3
+
4
+ def initialize(options)
5
+ @allow = options.fetch(:allow)
6
+ end
7
+
8
+ def open?
9
+ !allow
10
+ end
11
+
12
+ def process
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cb2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Pedro Belo
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: redis
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '3.1'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '3.1'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>'
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>'
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '3.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '3.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: timecop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '0.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '0.7'
69
+ description: Implementation of the circuit breaker pattern in Ruby
70
+ email: pedrobelo@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - Gemfile
76
+ - Gemfile.lock
77
+ - lib/breaker.rb
78
+ - lib/cb2.rb
79
+ - lib/error.rb
80
+ - lib/strategies/rolling_window.rb
81
+ - lib/strategies/stub.rb
82
+ homepage: http://github.com/pedro/cb2
83
+ licenses: []
84
+ metadata: {}
85
+ post_install_message:
86
+ rdoc_options: []
87
+ require_paths:
88
+ - lib
89
+ required_ruby_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ requirements: []
100
+ rubyforge_project:
101
+ rubygems_version: 2.2.2
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Circuit breaker
105
+ test_files: []
106
+ has_rdoc: