cb2 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: