semian 0.8.8 → 0.8.9

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
  SHA256:
3
- metadata.gz: 482a9a2fce30afb0e07d277552e3bab16bad193f7773977ba6c6c3c1f6805eb3
4
- data.tar.gz: f37534843a00fc5d9dd5dd4c060a088f47b183efc12e00699a4a82521b50f72f
3
+ metadata.gz: fe152464771999d2c44406ecfc6b9211f3288c52a0c8282175474c6a08898e03
4
+ data.tar.gz: 4ba4c7224d8da1fad03de8e47793639f85e9f714e57ce04534da7d06ba1d66bf
5
5
  SHA512:
6
- metadata.gz: a9f82b1d85f221594485c6ac5e16f803935df723b8893849b0126c2a7a77b50015e9162129030188f3ac538a76dd828909b36871fed8368b12b763c17a9d1d3a
7
- data.tar.gz: 1ea3b43414268a58e02d8dd53ed608e4bb576334a33e5948027557946cecb5b15bdc8e99aaabee4c00c1bb9737ba1740e67925abc9b052548099b0f32d360ef2
6
+ metadata.gz: fe5c8eccd45220845c26fbf67e91a328ca049ca91ed3e832461928bcadcca28b42951b84dcb200e618588f2d7715f61d08110b9238d110e5258bb2876fe402f4
7
+ data.tar.gz: 1b7e9d5f65abcaeca11d3d2ec6ab73f5247bf6cdb4c1e5739ac621c31144deed8d8fe9a35b5ffaec9f6ae6807551fab5bf421b34273518fbe5812768241f922e
@@ -100,17 +100,20 @@ set_semaphore_permissions(int sem_id, long permissions)
100
100
  int
101
101
  perform_semop(int sem_id, short index, short op, short flags, struct timespec *ts)
102
102
  {
103
+ int result;
103
104
  struct sembuf buf = { 0 };
104
105
 
105
106
  buf.sem_num = index;
106
107
  buf.sem_op = op;
107
108
  buf.sem_flg = flags;
108
109
 
109
- if (ts) {
110
- return semtimedop(sem_id, &buf, 1, ts);
111
- } else {
112
- return semop(sem_id, &buf, 1);
113
- }
110
+ int num_retries = 3;
111
+
112
+ do {
113
+ result = semtimedop(sem_id, &buf, 1, ts);
114
+ } while (result < 0 && errno == EINTR && num_retries-- > 0);
115
+
116
+ return result;
114
117
  }
115
118
 
116
119
  int
@@ -35,12 +35,10 @@ module Semian
35
35
  mark_resource_as_acquired(&block)
36
36
  end
37
37
  rescue ::Semian::OpenCircuitError => error
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
38
+ last_error = semian_resource.circuit_breaker.last_error
39
+ message = "#{error.message} caused by #{last_error.message}"
40
+ last_error = nil unless last_error.is_a?(Exception) # Net::HTTPServerError is not an exception
41
+ raise self.class::CircuitOpenError.new(semian_identifier, message), cause: last_error
44
42
  rescue ::Semian::BaseError => error
45
43
  raise self.class::ResourceBusyError.new(semian_identifier, error.message)
46
44
  rescue *resource_exceptions => error
@@ -6,7 +6,8 @@ module Semian
6
6
 
7
7
  attr_reader :name, :half_open_resource_timeout, :error_timeout, :state, :last_error
8
8
 
9
- def initialize(name, exceptions:, success_threshold:, error_threshold:, error_timeout:, implementation:, half_open_resource_timeout: nil)
9
+ def initialize(name, exceptions:, success_threshold:, error_threshold:,
10
+ error_timeout:, implementation:, half_open_resource_timeout: nil)
10
11
  @name = name.to_sym
11
12
  @success_count_threshold = success_threshold
12
13
  @error_count_threshold = error_threshold
@@ -17,6 +18,8 @@ module Semian
17
18
  @errors = implementation::SlidingWindow.new(max_size: @error_count_threshold)
18
19
  @successes = implementation::Integer.new
19
20
  @state = implementation::State.new
21
+
22
+ reset
20
23
  end
21
24
 
22
25
  def acquire(resource = nil, &block)
@@ -78,17 +81,20 @@ module Semian
78
81
  private
79
82
 
80
83
  def transition_to_close
84
+ notify_state_transition(:closed)
81
85
  log_state_transition(:closed)
82
86
  @state.close!
83
87
  @errors.clear
84
88
  end
85
89
 
86
90
  def transition_to_open
91
+ notify_state_transition(:open)
87
92
  log_state_transition(:open)
88
93
  @state.open!
89
94
  end
90
95
 
91
96
  def transition_to_half_open
97
+ notify_state_transition(:half_open)
92
98
  log_state_transition(:half_open)
93
99
  @state.half_open!
94
100
  @successes.reset
@@ -124,9 +130,14 @@ module Semian
124
130
  str << " success_count=#{@successes.value} error_count=#{@errors.size}"
125
131
  str << " success_count_threshold=#{@success_count_threshold} error_count_threshold=#{@error_count_threshold}"
126
132
  str << " error_timeout=#{@error_timeout} error_last_at=\"#{@errors.last}\""
133
+ str << " name=\"#{@name}\""
127
134
  Semian.logger.info(str)
128
135
  end
129
136
 
137
+ def notify_state_transition(new_state)
138
+ Semian.notify(:state_change, self, nil, nil, state: new_state)
139
+ end
140
+
130
141
  def disabled?
131
142
  ENV['SEMIAN_CIRCUIT_BREAKER_DISABLED'] || ENV['SEMIAN_DISABLED']
132
143
  end
data/lib/semian/mysql2.rb CHANGED
@@ -26,6 +26,7 @@ module Semian
26
26
  /Too many connections/i,
27
27
  /closed MySQL connection/i,
28
28
  /MySQL client is not connected/i,
29
+ /Timeout waiting for a response/i,
29
30
  )
30
31
 
31
32
  ResourceBusyError = ::Mysql2::ResourceBusyError
@@ -118,7 +119,7 @@ module Semian
118
119
  def acquire_semian_resource(*)
119
120
  super
120
121
  rescue ::Mysql2::Error => error
121
- if error.message =~ CONNECTION_ERROR || error.is_a?(PingFailure)
122
+ if error.is_a?(PingFailure) || (!error.is_a?(::Mysql2::SemianError) && error.message.match?(CONNECTION_ERROR))
122
123
  semian_resource.mark_failed(error)
123
124
  error.semian_identifier = semian_identifier
124
125
  end
data/lib/semian/redis.rb CHANGED
@@ -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.cause || e).to_s =~ /(can't resolve)|(name or service not known)/i
88
+ raise ResolveError.new(semian_identifier) if dns_resolve_failure?(e.cause || e)
89
89
  raise
90
90
  end
91
91
  end
@@ -111,6 +111,10 @@ module Semian
111
111
  return unless reply.message =~ /OOM command not allowed when used memory > 'maxmemory'\.\s*\z/
112
112
  raise ::Redis::OutOfMemoryError.new(reply.message)
113
113
  end
114
+
115
+ def dns_resolve_failure?(e)
116
+ e.to_s.match?(/(can't resolve)|(name or service not known)|(nodename nor servname provided, or not known)|(failure in name resolution)/i)
117
+ end
114
118
  end
115
119
  end
116
120
 
@@ -1,3 +1,3 @@
1
1
  module Semian
2
- VERSION = '0.8.8'
2
+ VERSION = '0.8.9'
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.8
4
+ version: 0.8.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Francis
@@ -10,36 +10,36 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2019-02-22 00:00:00.000000000 Z
13
+ date: 2019-09-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake-compiler
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - "~>"
19
+ - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '0.9'
21
+ version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - "~>"
26
+ - - ">="
27
27
  - !ruby/object:Gem::Version
28
- version: '0.9'
28
+ version: '0'
29
29
  - !ruby/object:Gem::Dependency
30
30
  name: rake
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - "<"
33
+ - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: '11.0'
35
+ version: '0'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - "<"
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: '11.0'
42
+ version: '0'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: timecop
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -69,7 +69,7 @@ dependencies:
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  - !ruby/object:Gem::Dependency
72
- name: byebug
72
+ name: pry-byebug
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - ">="
@@ -111,19 +111,19 @@ dependencies:
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0'
113
113
  - !ruby/object:Gem::Dependency
114
- name: thin
114
+ name: webrick
115
115
  requirement: !ruby/object:Gem::Requirement
116
116
  requirements:
117
- - - "~>"
117
+ - - ">="
118
118
  - !ruby/object:Gem::Version
119
- version: 1.7.2
119
+ version: '0'
120
120
  type: :development
121
121
  prerelease: false
122
122
  version_requirements: !ruby/object:Gem::Requirement
123
123
  requirements:
124
- - - "~>"
124
+ - - ">="
125
125
  - !ruby/object:Gem::Version
126
- version: 1.7.2
126
+ version: '0'
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: toxiproxy
129
129
  requirement: !ruby/object:Gem::Requirement
@@ -221,8 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
221
  - !ruby/object:Gem::Version
222
222
  version: '0'
223
223
  requirements: []
224
- rubyforge_project:
225
- rubygems_version: 2.7.6
224
+ rubygems_version: 3.0.3
226
225
  signing_key:
227
226
  specification_version: 4
228
227
  summary: Bulkheading for Ruby with SysV semaphores