semian 0.8.8 → 0.8.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/semian/sysv_semaphores.c +8 -5
- data/lib/semian/adapter.rb +4 -6
- data/lib/semian/circuit_breaker.rb +12 -1
- data/lib/semian/mysql2.rb +2 -1
- data/lib/semian/redis.rb +5 -1
- data/lib/semian/version.rb +1 -1
- metadata +17 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe152464771999d2c44406ecfc6b9211f3288c52a0c8282175474c6a08898e03
|
4
|
+
data.tar.gz: 4ba4c7224d8da1fad03de8e47793639f85e9f714e57ce04534da7d06ba1d66bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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
|
data/lib/semian/adapter.rb
CHANGED
@@ -35,12 +35,10 @@ module Semian
|
|
35
35
|
mark_resource_as_acquired(&block)
|
36
36
|
end
|
37
37
|
rescue ::Semian::OpenCircuitError => error
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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:,
|
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.
|
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)
|
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
|
|
data/lib/semian/version.rb
CHANGED
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.
|
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
|
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
|
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
|
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: '
|
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: '
|
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:
|
114
|
+
name: webrick
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
116
116
|
requirements:
|
117
|
-
- - "
|
117
|
+
- - ">="
|
118
118
|
- !ruby/object:Gem::Version
|
119
|
-
version:
|
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:
|
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
|
-
|
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
|