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 +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
|