semian 0.8.3 → 0.8.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 36b4357747467cafab6b0c42471f8cfe169507aa
4
- data.tar.gz: 5b1283ad1a0d7cd9df8b3e82ac14e73a89765d69
3
+ metadata.gz: f71cd497f50581f77346713c46ca0c441a28b483
4
+ data.tar.gz: c86d7dec61a304618f9b7adedc192e8d52fceba0
5
5
  SHA512:
6
- metadata.gz: e9102fa0caff36c3bc4235a0a4e0df3eec20ae86b474ec9fea59c38cff3ae075d357cef424c7f820afddd70e423798c75a27c3a12c68e2204944359a406a9b1c
7
- data.tar.gz: a29c0ab88f8c05c9111912ec20b61de5104fad3675997279e235a5adabc931811f8b58e71faca04742e5d5fe18885b6cf99b3ae622136e02d3fbf594aa95504e
6
+ metadata.gz: 9c0275ee9e483ce0a9accbf93ec59a93c97961b42d73dde6509cca45a245960f935b211107f03850eb172e07f4bc3b04b2855d423389255dc0d4d6abf72dc089
7
+ data.tar.gz: 64c9cc56813af4008f23fdd6e70fb9023f8e4b047846b892a7ad23b27a6444df9de2999f8422c266bd8bc918642ae8626174fe8adb8e4d24befbcb554f984d5a
@@ -35,7 +35,12 @@ module Semian
35
35
  mark_resource_as_acquired(&block)
36
36
  end
37
37
  rescue ::Semian::OpenCircuitError => error
38
- raise self.class::CircuitOpenError.new(semian_identifier, error.message)
38
+ begin
39
+ raise semian_resource.circuit_breaker.last_error
40
+ rescue
41
+ last_error_message = semian_resource.circuit_breaker.last_error.message
42
+ raise self.class::CircuitOpenError.new(semian_identifier, "#{error.message} caused by #{last_error_message}")
43
+ end
39
44
  rescue ::Semian::BaseError => error
40
45
  raise self.class::ResourceBusyError.new(semian_identifier, error.message)
41
46
  rescue *resource_exceptions => error
@@ -2,9 +2,9 @@ module Semian
2
2
  class CircuitBreaker #:nodoc:
3
3
  extend Forwardable
4
4
 
5
- def_delegators :@state, :closed?, :open?, :half_open!
5
+ def_delegators :@state, :closed?, :open?, :half_open?
6
6
 
7
- attr_reader :name, :half_open_resource_timeout
7
+ attr_reader :name, :half_open_resource_timeout, :error_timeout, :state, :last_error
8
8
 
9
9
  def initialize(name, exceptions:, success_threshold:, error_threshold:, error_timeout:, implementation:, half_open_resource_timeout: nil)
10
10
  @name = name.to_sym
@@ -21,7 +21,7 @@ module Semian
21
21
 
22
22
  def acquire(resource = nil, &block)
23
23
  return yield if disabled?
24
- half_open! if half_open?
24
+ transition_to_half_open if transition_to_half_open?
25
25
 
26
26
  raise OpenCircuitError unless request_allowed?
27
27
 
@@ -37,33 +37,34 @@ module Semian
37
37
  result
38
38
  end
39
39
 
40
- def half_open?
41
- (open? && error_timeout_expired?) || @state.half_open?
40
+ def transition_to_half_open?
41
+ open? && error_timeout_expired? && !half_open?
42
42
  end
43
43
 
44
44
  def request_allowed?
45
- closed? || half_open?
45
+ closed? || half_open? || transition_to_half_open?
46
46
  end
47
47
 
48
- def mark_failed(_error)
48
+ def mark_failed(error)
49
+ push_error(error)
49
50
  push_time(@errors)
50
51
  if closed?
51
- open if error_threshold_reached?
52
+ transition_to_open if error_threshold_reached?
52
53
  elsif half_open?
53
- open
54
+ transition_to_open
54
55
  end
55
56
  end
56
57
 
57
58
  def mark_success
58
59
  return unless half_open?
59
60
  @successes.increment
60
- close if success_threshold_reached?
61
+ transition_to_close if success_threshold_reached?
61
62
  end
62
63
 
63
64
  def reset
64
65
  @errors.clear
65
66
  @successes.reset
66
- close
67
+ transition_to_close
67
68
  end
68
69
 
69
70
  def destroy
@@ -74,20 +75,20 @@ module Semian
74
75
 
75
76
  private
76
77
 
77
- def close
78
+ def transition_to_close
78
79
  log_state_transition(:closed)
79
- @state.close
80
+ @state.close!
80
81
  @errors.clear
81
82
  end
82
83
 
83
- def open
84
+ def transition_to_open
84
85
  log_state_transition(:open)
85
- @state.open
86
+ @state.open!
86
87
  end
87
88
 
88
- def half_open
89
+ def transition_to_half_open
89
90
  log_state_transition(:half_open)
90
- @state.half_open
91
+ @state.half_open!
91
92
  @successes.reset
92
93
  end
93
94
 
@@ -105,6 +106,10 @@ module Semian
105
106
  Time.at(last_error_time) + @error_timeout < Time.now
106
107
  end
107
108
 
109
+ def push_error(error)
110
+ @last_error = error
111
+ end
112
+
108
113
  def push_time(window, time: Time.now)
109
114
  window.reject! { |err_time| err_time + @error_timeout < time.to_i }
110
115
  window << time.to_i
@@ -125,15 +130,14 @@ module Semian
125
130
  end
126
131
 
127
132
  def maybe_with_half_open_resource_timeout(resource, &block)
128
- result = nil
129
-
130
- if half_open? && @half_open_resource_timeout && resource.respond_to?(:with_resource_timeout)
131
- resource.with_resource_timeout(@half_open_resource_timeout) do
132
- result = block.call
133
+ result =
134
+ if half_open? && @half_open_resource_timeout && resource.respond_to?(:with_resource_timeout)
135
+ resource.with_resource_timeout(@half_open_resource_timeout) do
136
+ block.call
137
+ end
138
+ else
139
+ block.call
133
140
  end
134
- else
135
- result = block.call
136
- end
137
141
 
138
142
  result
139
143
  end
@@ -90,6 +90,19 @@ module Semian
90
90
  end
91
91
  end
92
92
 
93
+ def with_resource_timeout(timeout)
94
+ prev_read_timeout = read_timeout
95
+ prev_open_timeout = open_timeout
96
+ begin
97
+ self.read_timeout = timeout
98
+ self.open_timeout = timeout
99
+ yield
100
+ ensure
101
+ self.read_timeout = prev_read_timeout
102
+ self.open_timeout = prev_open_timeout
103
+ end
104
+ end
105
+
93
106
  private
94
107
 
95
108
  def handle_error_responses(result)
@@ -85,7 +85,7 @@ module Semian
85
85
  begin
86
86
  raw_connect
87
87
  rescue SocketError, RuntimeError => e
88
- raise ResolveError.new(semian_identifier) if e.message =~ /(can't resolve)|(name or service not known)/i
88
+ raise ResolveError.new(semian_identifier) if e.cause.to_s =~ /(can't resolve)|(name or service not known)/i
89
89
  raise
90
90
  end
91
91
  end
@@ -19,11 +19,11 @@ module Semian
19
19
  value == :half_open
20
20
  end
21
21
 
22
- def open
22
+ def open!
23
23
  @value = :open
24
24
  end
25
25
 
26
- def close
26
+ def close!
27
27
  @value = :closed
28
28
  end
29
29
 
@@ -32,7 +32,7 @@ module Semian
32
32
  end
33
33
 
34
34
  def reset
35
- close
35
+ close!
36
36
  end
37
37
 
38
38
  def destroy
@@ -1,3 +1,3 @@
1
1
  module Semian
2
- VERSION = '0.8.3'
2
+ VERSION = '0.8.4'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.3
4
+ version: 0.8.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Francis
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-08-20 00:00:00.000000000 Z
13
+ date: 2018-10-19 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake-compiler