rcb 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61b7b710d6681c43cbe7b7d538d0eeda7199ee7e7c892e3aa2b0ddd1455a5a08
4
- data.tar.gz: 18449ecc9021e6dace52a8b07834544564234d1fe06170d81830a0c36aca5021
3
+ metadata.gz: '029e8ceda425ad3aea544142ab9307fd74ebff19fa98e359d791d820528f5638'
4
+ data.tar.gz: daf71c637318058ef6647531544c4fbe77404e08e0e705778ea77623f53d461d
5
5
  SHA512:
6
- metadata.gz: 263813bdacad4713d2cf411aa6f5caae798166290142e96aabce52c2b1bd95220fd008fbbd46188afd3f59834c58edcacc43d0537865cd0e7e0b90260829966f
7
- data.tar.gz: 95c4afc987cef799fbf40dbb29bbcaf08a94110d5b7996d076560951430975894bb2f35fa29a69b1cc24a6022ca54ff25f4587ff39e0d7b525cfff055651f67a
6
+ metadata.gz: 79cf1a6056c40f5abf501905ea0a3ac12e98eaaafd86a45e537b4db66ce343b6bc7c759c5ba74a7c7a0f1c7d66ec4e4c4f881c8e02f6627cbb89acab426fba29
7
+ data.tar.gz: b268096b37b3a3d13f7a7367ad5491b02dd65bbf21aa47637caa7f7afb67586470917b984913cf016e23d0d0c8020cddc0a4dbce16067189a2a79b95b4bc8df3
@@ -0,0 +1,22 @@
1
+ name: test
2
+ on: [push, pull_request]
3
+
4
+ jobs:
5
+ build:
6
+ runs-on: ubuntu-latest
7
+
8
+ steps:
9
+ - uses: actions/checkout@v1
10
+
11
+ - name: Set up Ruby 2.7
12
+ uses: clupprich/ruby-build-action@master
13
+ with:
14
+ ruby-version: 2.7.0
15
+
16
+ - name: Bundle install
17
+ run: |
18
+ bundle -j 4 --path vendor/bundle
19
+
20
+ - name: Run Tests
21
+ run: |
22
+ bundle exec rake test
data/README.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # Rcb - Ruby Circuit Breaker
2
2
 
3
+ [![rcb](https://badge.fury.io/rb/rcb.svg)](https://badge.fury.io/rb/rcb)
4
+ [![Actions Status](https://github.com/petitviolet/rcb/workflows/test/badge.svg)](https://github.com/petitviolet/rcb/actions)
5
+
3
6
  [Circuit Breaker](https://martinfowler.com/bliki/CircuitBreaker.html) implementation for/by Ruby.
4
7
  CircuitBreaker is a great pattern to build robust system consists of bunch of microservices.
5
8
 
6
9
  - Close
7
- - A operational state
10
+ - An operational state
8
11
  - Open
9
12
  - A not operational state
10
13
  - Half Open
data/lib/rcb.rb CHANGED
@@ -3,9 +3,9 @@ require_relative "./rcb/configuration"
3
3
 
4
4
  module Rcb
5
5
  module ClassMethods
6
- def for(tag, max_failure_count: nil, reset_timeout_msec: nil)
6
+ def for(tag, open_condition: nil, reset_timeout_msec: nil)
7
7
  config = Rcb::Configurations.for(tag,
8
- max_failure_count: max_failure_count,
8
+ open_condition: open_condition,
9
9
  reset_timeout_msec: reset_timeout_msec)
10
10
  Instance.new(config)
11
11
  end
@@ -1,53 +1,83 @@
1
1
  require 'logger'
2
+ require 'rstructural'
2
3
 
3
4
  module Rcb
4
- Config = Struct.new(:tag, :max_failure_count, :reset_timeout_msec)do
5
- MAX_FAILURE_COUNT = 0.freeze
6
- RESET_TIMEOUT_MSEC = 0.freeze
5
+ OpenCondition = Rstruct.new(:max_failure_count, :window_msec) do
6
+ self::DEFAULT = new(3, 1000).freeze
7
+ end
8
+
9
+ Config = Rstruct.new(:tag, :open_condition, :reset_timeout_msec) do
10
+ self::RESET_TIMEOUT_MSEC = 1000.freeze
7
11
 
8
12
  @logger = Logger.new($stderr)
9
13
 
10
- def self.create(tag, max_failure_count: nil, reset_timeout_msec: nil)
14
+ def self.create(tag, open_condition: nil, reset_timeout_msec: nil)
11
15
  raise 'Rcb tag must not be nil' if tag.nil?
12
16
 
13
- if max_failure_count.nil? && reset_timeout_msec.nil?
17
+ if open_condition.nil? && reset_timeout_msec.nil?
14
18
  @logger.warn("Rcb for '#{tag}' is not configured!")
15
19
  end
16
20
 
17
21
  Config.new(
18
22
  tag.to_s.to_sym,
19
- max_failure_count || MAX_FAILURE_COUNT,
20
- reset_timeout_msec || RESET_TIMEOUT_MSEC
23
+ open_condition || OpenCondition::DEFAULT,
24
+ reset_timeout_msec || Config::RESET_TIMEOUT_MSEC
21
25
  )
22
26
  end
23
27
  end
24
28
 
25
- class ConfigBuilder
26
- def initialize(tag)
27
- @tag = tag
28
- @max_failure_count = nil
29
- @reset_timeout_msec = nil
30
- end
29
+ module DSL
30
+ class OpenConditionBuilder
31
+ def initialize
32
+ @max_failure_count = nil
33
+ @window_msec = nil
34
+ end
31
35
 
32
- def max_failure_count(num)
33
- @max_failure_count = num
34
- end
36
+ def max_failure_count(count)
37
+ @max_failure_count = count
38
+ end
39
+
40
+ def window_msec(msec)
41
+ @window_msec = msec
42
+ end
35
43
 
36
- def reset_timeout_msec(msec)
37
- @reset_timeout_msec = msec
44
+ def build
45
+ Rcb::OpenCondition.new(@max_failure_count, @window_msec)
46
+ end
38
47
  end
39
48
 
40
- def build
41
- Config.create(
42
- @tag,
43
- max_failure_count:@max_failure_count,
44
- reset_timeout_msec: @reset_timeout_msec
45
- ).freeze
49
+ class ConfigBuilder
50
+ def initialize(tag)
51
+ @tag = tag
52
+ @open_condition_builder = OpenConditionBuilder.new
53
+ @reset_timeout_msec = nil
54
+ end
55
+
56
+ def open_condition(hash = nil)
57
+ if hash
58
+ @open_condition_builder.max_failure_count hash[:max_failure_count]
59
+ @open_condition_builder.window_msec hash[:window_msec]
60
+ else
61
+ @open_condition_builder
62
+ end
63
+ end
64
+
65
+ def reset_timeout_msec(msec)
66
+ @reset_timeout_msec = msec
67
+ end
68
+
69
+ def build
70
+ Rcb::Config.create(
71
+ @tag,
72
+ open_condition: @open_condition_builder.build,
73
+ reset_timeout_msec: @reset_timeout_msec
74
+ ).freeze
75
+ end
46
76
  end
47
77
  end
48
78
 
49
79
  def Rcb.configure(tag, &block)
50
- c = ConfigBuilder.new(tag.to_s.to_sym)
80
+ c = DSL::ConfigBuilder.new(tag.to_s.to_sym)
51
81
  .tap { |cb| block.call(cb) }
52
82
  .build
53
83
 
@@ -57,9 +87,9 @@ module Rcb
57
87
  module Configurations
58
88
  @configs = {}
59
89
 
60
- def self.for(tag, max_failure_count: nil, reset_timeout_msec: nil)
90
+ def self.for(tag, open_condition: nil, reset_timeout_msec: nil)
61
91
  @configs[tag.to_s.to_sym] || Config.create(tag,
62
- max_failure_count: max_failure_count,
92
+ open_condition: open_condition,
63
93
  reset_timeout_msec: reset_timeout_msec)
64
94
  end
65
95
 
@@ -1,4 +1,3 @@
1
- require 'byebug'
2
1
  require 'rstructural'
3
2
  require_relative './state'
4
3
  require_relative './configuration'
@@ -5,18 +5,20 @@ require_relative './error'
5
5
  module Rcb::State
6
6
  extend ADT
7
7
 
8
- Close = data :failure_count do
9
- def self.create(failure_count = 0)
10
- new(failure_count)
8
+ Close = data :failure_times do
9
+ def self.create
10
+ new([])
11
11
  end
12
12
 
13
- def run(config, &block)
13
+ def run(config, now: Time.now.utc, &block)
14
14
  case try_call(&block)
15
15
  in Either::Right[result]
16
16
  Rcb::Result::Ok.new(self, result)
17
17
  in Either::Left[e]
18
- if config.max_failure_count > failure_count
19
- Rcb::Result::Ng.new(Close.create(failure_count + 1), e)
18
+ old_limit = now - (config.open_condition.window_msec / 1000.0)
19
+ refreshed_failure_times = failure_times.filter { |ft| old_limit <= ft } + [now]
20
+ if refreshed_failure_times.size < config.open_condition.max_failure_count
21
+ Rcb::Result::Ng.new(Close.new(refreshed_failure_times), e)
20
22
  else
21
23
  Rcb::Result::Ng.new(Open.create, e)
22
24
  end
@@ -1,8 +1,6 @@
1
- require_relative 'lib/rcb/version'
2
-
3
1
  Gem::Specification.new do |spec|
4
2
  spec.name = "rcb"
5
- spec.version = Rcb::VERSION
3
+ spec.version = '0.2.0'
6
4
  spec.authors = ["petitviolet"]
7
5
  spec.email = ["violethero0820@gmail.com"]
8
6
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rcb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - petitviolet
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-02-22 00:00:00.000000000 Z
11
+ date: 2020-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rstructural
@@ -73,6 +73,7 @@ executables: []
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - ".github/workflows/action.yaml"
76
77
  - ".gitignore"
77
78
  - CODE_OF_CONDUCT.md
78
79
  - Gemfile
@@ -87,7 +88,6 @@ files:
87
88
  - lib/rcb/instance.rb
88
89
  - lib/rcb/result.rb
89
90
  - lib/rcb/state.rb
90
- - lib/rcb/version.rb
91
91
  - rcb.gemspec
92
92
  homepage: https://github.com/petitviolet/rcb
93
93
  licenses:
@@ -1,3 +0,0 @@
1
- module Rcb
2
- VERSION = "0.1.0"
3
- end