semian 0.11.7 → 0.12.0

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: e136dd51d96e89f74e2ea3b4d838a86a265dd097c44c61601daa35dbdf60aba0
4
- data.tar.gz: 9f42e7eba02dc6f94547d5a8c98ace41672abc9c4ec4ce093c5c8e4c160163a2
3
+ metadata.gz: da759d0f61fb02cfc01d7d26182f2d0b1a1be105f310bae112f07f1141c278b1
4
+ data.tar.gz: 782e6184ff4a169ccd16dea60c0d3bf22b885558c53eb455756516aa5c48addd
5
5
  SHA512:
6
- metadata.gz: dd3861895b3aaf7de70a693c55276d9fc290cfd51a0460491759d106e0a9b9ea1d72bfbb7c3d31b7cf44bdbde3d2c7ce28742a25032375432c570aef325164da
7
- data.tar.gz: 6cad2df1f48a514ee8b0122ce1b15fa9c6af84c76dfa0b435205086f6fd1d70d60c87f00eb33282caffab8bafb4500d5a099e8a4a599d3905064d6f89e555d4b
6
+ metadata.gz: d19b1bbbd06678f4287ff31aef7297a8036a0f7ab7743e62eb1c697378adddbe8ed182eb7f7c6855b98874a8b8a53a706b54fe6e75e1b06db3c3963d604a3e37
7
+ data.tar.gz: 3d661891b20e8ccd1aad67b26a192229133e91d7d1ccd340eb38515010c4dbdc7987d89c9cd293b2c3ec06068417a3d45ee5d5003e3e02a0c58a0ea6a98122f8
@@ -57,7 +57,7 @@ module Semian
57
57
  end
58
58
 
59
59
  def resource_exceptions
60
- []
60
+ raise NotImplementedError.new("Semian adapters must implement a `resource_exceptions` method")
61
61
  end
62
62
 
63
63
  def resource_already_acquired?
@@ -7,10 +7,11 @@ module Semian
7
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:,
10
- error_timeout:, implementation:, half_open_resource_timeout: nil)
10
+ error_timeout:, implementation:, half_open_resource_timeout: nil, error_threshold_timeout: nil)
11
11
  @name = name.to_sym
12
12
  @success_count_threshold = success_threshold
13
13
  @error_count_threshold = error_threshold
14
+ @error_threshold_timeout = error_threshold_timeout || error_timeout
14
15
  @error_timeout = error_timeout
15
16
  @exceptions = exceptions
16
17
  @half_open_resource_timeout = half_open_resource_timeout
@@ -124,7 +125,7 @@ module Semian
124
125
  end
125
126
 
126
127
  def push_time(window, time: Time.now)
127
- window.reject! { |err_time| err_time + @error_timeout < time.to_i }
128
+ window.reject! { |err_time| err_time + @error_threshold_timeout < time.to_i }
128
129
  window << time.to_i
129
130
  end
130
131
 
data/lib/semian/mysql2.rb CHANGED
@@ -101,6 +101,11 @@ module Semian
101
101
 
102
102
  private
103
103
 
104
+ EXCEPTIONS = [].freeze
105
+ def resource_exceptions
106
+ EXCEPTIONS
107
+ end
108
+
104
109
  def query_whitelisted?(sql, *)
105
110
  QUERY_WHITELIST =~ sql
106
111
  rescue ArgumentError
data/lib/semian/rails.rb CHANGED
@@ -2,6 +2,8 @@ require 'active_record/connection_adapters/abstract_adapter'
2
2
 
3
3
  class ActiveRecord::ConnectionAdapters::AbstractAdapter
4
4
  def semian_resource
5
- @connection.semian_resource
5
+ # support for https://github.com/rails/rails/commit/d86fd6415c0dfce6fadb77e74696cf728e5eb76b
6
+ connection = instance_variable_defined?(:@raw_connection) ? @raw_connection : @connection
7
+ connection.semian_resource
6
8
  end
7
9
  end
data/lib/semian/redis.rb CHANGED
@@ -138,7 +138,7 @@ module Semian
138
138
 
139
139
  def raise_if_out_of_memory(reply)
140
140
  return unless reply.is_a?(::Redis::CommandError)
141
- return unless reply.message =~ /OOM command not allowed when used memory > 'maxmemory'\.\s*\z/
141
+ return unless reply.message.start_with?("OOM ")
142
142
  raise ::Redis::OutOfMemoryError.new(reply.message)
143
143
  end
144
144
 
@@ -0,0 +1,111 @@
1
+ require 'semian/adapter'
2
+ require 'redis-client'
3
+
4
+ class RedisClient
5
+ ConnectionError.include(::Semian::AdapterError)
6
+
7
+ class SemianError < ConnectionError
8
+ def initialize(semian_identifier, *args)
9
+ super(*args)
10
+ @semian_identifier = semian_identifier
11
+ end
12
+ end
13
+
14
+ ResourceBusyError = Class.new(SemianError)
15
+ CircuitOpenError = Class.new(SemianError)
16
+
17
+ module SemianConfig
18
+ attr_reader :raw_semian_options
19
+
20
+ def initialize(semian: nil, **kwargs)
21
+ super(**kwargs)
22
+
23
+ @raw_semian_options = semian
24
+ end
25
+
26
+ def semian_identifier
27
+ @semian_identifier ||= begin
28
+ name = (semian_options && semian_options[:name]) || "#{host}:#{port}/#{db}"
29
+ :"redis_#{name}"
30
+ end
31
+ end
32
+
33
+ define_method(:semian_options, Semian::Adapter.instance_method(:semian_options))
34
+ end
35
+
36
+ Config.include(SemianConfig)
37
+ SentinelConfig.include(SemianConfig)
38
+ end
39
+
40
+ module Semian
41
+ module RedisClientCommon
42
+ def with_resource_timeout(temp_timeout)
43
+ connect_timeout = self.connect_timeout
44
+ read_timeout = self.read_timeout
45
+ write_timeout = self.write_timeout
46
+
47
+ begin
48
+ self.timeout = temp_timeout
49
+ yield
50
+ ensure
51
+ self.connect_timeout = connect_timeout
52
+ self.read_timeout = read_timeout
53
+ self.write_timeout = write_timeout
54
+ end
55
+ end
56
+
57
+ def semian_identifier
58
+ config.semian_identifier
59
+ end
60
+
61
+ private
62
+
63
+ def semian_options
64
+ config.semian_options
65
+ end
66
+
67
+ def raw_semian_options
68
+ config.raw_semian_options
69
+ end
70
+ end
71
+
72
+ module RedisClient
73
+ EXCEPTIONS = [::RedisClient::ConnectionError]
74
+
75
+ include Semian::Adapter
76
+ include RedisClientCommon
77
+
78
+ private
79
+
80
+ def resource_exceptions
81
+ EXCEPTIONS
82
+ end
83
+
84
+ def ensure_connected(retryable: true)
85
+ if block_given?
86
+ super do |connection|
87
+ acquire_semian_resource(adapter: :redis_client, scope: :query) do
88
+ yield connection
89
+ end
90
+ end
91
+ else
92
+ super
93
+ end
94
+ end
95
+
96
+ def connect
97
+ acquire_semian_resource(adapter: :redis_client, scope: :connection) do
98
+ super
99
+ end
100
+ end
101
+ end
102
+
103
+ module RedisClientPool
104
+ include RedisClientCommon
105
+ define_method(:semian_resource, Semian::Adapter.instance_method(:semian_resource))
106
+ define_method(:clear_semian_resource, Semian::Adapter.instance_method(:clear_semian_resource))
107
+ end
108
+ end
109
+
110
+ RedisClient.prepend(Semian::RedisClient)
111
+ RedisClient::Pooled.prepend(Semian::RedisClient)
@@ -1,3 +1,3 @@
1
1
  module Semian
2
- VERSION = '0.11.7'
2
+ VERSION = '0.12.0'
3
3
  end
data/lib/semian.rb CHANGED
@@ -190,6 +190,11 @@ module Semian
190
190
  end
191
191
  end
192
192
 
193
+ def destroy_all_resources
194
+ resources.values.each(&:destroy)
195
+ resources.clear
196
+ end
197
+
193
198
  # Unregister will not destroy the semian resource, but it will
194
199
  # remove it from the hash of registered resources, and decrease
195
200
  # the number of registered workers.
@@ -257,6 +262,7 @@ module Semian
257
262
  name,
258
263
  success_threshold: options[:success_threshold],
259
264
  error_threshold: options[:error_threshold],
265
+ error_threshold_timeout: options[:error_threshold_timeout],
260
266
  error_timeout: options[:error_timeout],
261
267
  exceptions: Array(exceptions) + [::Semian::BaseError],
262
268
  half_open_resource_timeout: options[:half_open_resource_timeout],
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.11.7
4
+ version: 0.12.0
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: 2022-01-12 00:00:00.000000000 Z
13
+ date: 2022-04-29 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake-compiler
@@ -110,6 +110,20 @@ dependencies:
110
110
  - - ">="
111
111
  - !ruby/object:Gem::Version
112
112
  version: '0'
113
+ - !ruby/object:Gem::Dependency
114
+ name: redis-client
115
+ requirement: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: 0.2.0
120
+ type: :development
121
+ prerelease: false
122
+ version_requirements: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ">="
125
+ - !ruby/object:Gem::Version
126
+ version: 0.2.0
113
127
  - !ruby/object:Gem::Dependency
114
128
  name: webrick
115
129
  requirement: !ruby/object:Gem::Requirement
@@ -225,6 +239,7 @@ files:
225
239
  - lib/semian/protected_resource.rb
226
240
  - lib/semian/rails.rb
227
241
  - lib/semian/redis.rb
242
+ - lib/semian/redis_client.rb
228
243
  - lib/semian/resource.rb
229
244
  - lib/semian/simple_integer.rb
230
245
  - lib/semian/simple_sliding_window.rb