semian 0.12.0 → 0.13.2

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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Semian
2
- VERSION = '0.12.0'
4
+ VERSION = "0.13.2"
3
5
  end
data/lib/semian.rb CHANGED
@@ -1,19 +1,21 @@
1
- require 'forwardable'
2
- require 'logger'
3
- require 'weakref'
4
- require 'thread'
5
-
6
- require 'semian/version'
7
- require 'semian/instrumentable'
8
- require 'semian/platform'
9
- require 'semian/resource'
10
- require 'semian/circuit_breaker'
11
- require 'semian/protected_resource'
12
- require 'semian/unprotected_resource'
13
- require 'semian/simple_sliding_window'
14
- require 'semian/simple_integer'
15
- require 'semian/simple_state'
16
- require 'semian/lru_hash'
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+ require "logger"
5
+ require "weakref"
6
+ require "thread"
7
+
8
+ require "semian/version"
9
+ require "semian/instrumentable"
10
+ require "semian/platform"
11
+ require "semian/resource"
12
+ require "semian/circuit_breaker"
13
+ require "semian/protected_resource"
14
+ require "semian/unprotected_resource"
15
+ require "semian/simple_sliding_window"
16
+ require "semian/simple_integer"
17
+ require "semian/simple_state"
18
+ require "semian/lru_hash"
17
19
 
18
20
  #
19
21
  # === Overview
@@ -56,9 +58,17 @@ require 'semian/lru_hash'
56
58
  #
57
59
  # ===== Registering a resource
58
60
  #
59
- # Semian.register(:mysql_shard0, tickets: 10, timeout: 0.5, error_threshold: 3, error_timeout: 10, success_threshold: 2)
61
+ # Semian.register(
62
+ # :mysql_shard0,
63
+ # tickets: 10,
64
+ # timeout: 0.5,
65
+ # error_threshold: 3,
66
+ # error_timeout: 10,
67
+ # success_threshold: 2,
68
+ # )
60
69
  #
61
- # This registers a new resource called <code>:mysql_shard0</code> that has 10 tickets and a default timeout of 500 milliseconds.
70
+ # This registers a new resource called <code>:mysql_shard0</code> that has 10 tickets and
71
+ # a default timeout of 500 milliseconds.
62
72
  #
63
73
  # After 3 failures in the span of 10 seconds the circuit will be open.
64
74
  # After an additional 10 seconds it will transition to half-open.
@@ -70,8 +80,8 @@ require 'semian/lru_hash'
70
80
  # # Perform a MySQL query here
71
81
  # end
72
82
  #
73
- # This acquires a ticket for the <code>:mysql_shard0</code> resource. If we use the example above, the ticket count would
74
- # be lowered to 9 when block is executed, then raised to 10 when the block completes.
83
+ # This acquires a ticket for the <code>:mysql_shard0</code> resource. If we use the example above,
84
+ # the ticket count would be lowered to 9 when block is executed, then raised to 10 when the block completes.
75
85
  #
76
86
  # ===== Overriding the default timeout
77
87
  #
@@ -79,7 +89,8 @@ require 'semian/lru_hash'
79
89
  # # Perform a MySQL query here
80
90
  # end
81
91
  #
82
- # This is the same as the previous example, but overrides the timeout from the default value of 500 milliseconds to 1 second.
92
+ # This is the same as the previous example, but overrides the timeout
93
+ # from the default value of 500 milliseconds to 1 second.
83
94
  module Semian
84
95
  extend self
85
96
  extend Instrumentable
@@ -91,12 +102,14 @@ module Semian
91
102
  OpenCircuitError = Class.new(BaseError)
92
103
 
93
104
  attr_accessor :maximum_lru_size, :minimum_lru_time, :default_permissions, :namespace
105
+
94
106
  self.maximum_lru_size = 500
95
107
  self.minimum_lru_time = 300
96
108
  self.default_permissions = 0660
97
109
 
98
110
  def issue_disabled_semaphores_warning
99
111
  return if defined?(@warning_issued)
112
+
100
113
  @warning_issued = true
101
114
  if !sysv_semaphores_supported?
102
115
  logger.info("Semian sysv semaphores are not supported on #{RUBY_PLATFORM} - all operations will no-op")
@@ -119,7 +132,7 @@ module Semian
119
132
 
120
133
  attr_accessor :logger
121
134
 
122
- self.logger = Logger.new(STDERR)
135
+ self.logger = Logger.new($stderr)
123
136
 
124
137
  # Registers a resource.
125
138
  #
@@ -161,7 +174,7 @@ module Semian
161
174
  bulkhead = create_bulkhead(name, **options)
162
175
 
163
176
  if circuit_breaker.nil? && bulkhead.nil?
164
- raise ArgumentError, 'Both bulkhead and circuitbreaker cannot be disabled.'
177
+ raise ArgumentError, "Both bulkhead and circuitbreaker cannot be disabled."
165
178
  end
166
179
 
167
180
  resources[name] = ProtectedResource.new(name, bulkhead, circuit_breaker)
@@ -170,11 +183,10 @@ module Semian
170
183
  def retrieve_or_register(name, **args)
171
184
  # If consumer who retrieved / registered by a Semian::Adapter, keep track
172
185
  # of who the consumer was so that we can clear the resource reference if needed.
173
- if consumer = args.delete(:consumer)
174
- if consumer.class.include?(Semian::Adapter)
175
- consumers[name] ||= []
176
- consumers[name] << WeakRef.new(consumer)
177
- end
186
+ consumer = args.delete(:consumer)
187
+ if consumer&.class&.include?(Semian::Adapter)
188
+ consumers[name] ||= []
189
+ consumers[name] << WeakRef.new(consumer)
178
190
  end
179
191
  self[name] || register(name, **args)
180
192
  end
@@ -185,9 +197,8 @@ module Semian
185
197
  end
186
198
 
187
199
  def destroy(name)
188
- if resource = resources.delete(name)
189
- resource.destroy
190
- end
200
+ resource = resources.delete(name)
201
+ resource&.destroy
191
202
  end
192
203
 
193
204
  def destroy_all_resources
@@ -204,17 +215,16 @@ module Semian
204
215
  # Also clears any semian_resources
205
216
  # in use by any semian adapters if the weak reference is still alive.
206
217
  def unregister(name)
207
- if resource = resources.delete(name)
208
- resource.bulkhead.unregister_worker if resource.bulkhead
218
+ resource = resources.delete(name)
219
+ if resource
220
+ resource.bulkhead&.unregister_worker
209
221
  consumers_for_resource = consumers.delete(name) || []
210
222
  consumers_for_resource.each do |consumer|
211
- begin
212
- if consumer.weakref_alive?
213
- consumer.clear_semian_resource
214
- end
215
- rescue WeakRef::RefError
216
- next
223
+ if consumer.weakref_alive?
224
+ consumer.clear_semian_resource
217
225
  end
226
+ rescue WeakRef::RefError
227
+ next
218
228
  end
219
229
  end
220
230
  end
@@ -243,6 +253,7 @@ module Semian
243
253
 
244
254
  def thread_safe?
245
255
  return @thread_safe if defined?(@thread_safe)
256
+
246
257
  @thread_safe = true
247
258
  end
248
259
 
@@ -255,6 +266,7 @@ module Semian
255
266
  def create_circuit_breaker(name, **options)
256
267
  circuit_breaker = options.fetch(:circuit_breaker, true)
257
268
  return unless circuit_breaker
269
+
258
270
  require_keys!([:success_threshold, :error_threshold, :error_timeout], options)
259
271
 
260
272
  exceptions = options[:exceptions] || []
@@ -277,8 +289,8 @@ module Semian
277
289
  unless options[:thread_safety_disabled].nil?
278
290
  logger.info(
279
291
  "NOTE: thread_safety_disabled will be replaced by a global setting" \
280
- "Semian is thread safe by default. It is possible" \
281
- "to modify the value by using Semian.thread_safe=",
292
+ "Semian is thread safe by default. It is possible" \
293
+ "to modify the value by using Semian.thread_safe=",
282
294
  )
283
295
  end
284
296
 
@@ -292,7 +304,11 @@ module Semian
292
304
 
293
305
  permissions = options[:permissions] || default_permissions
294
306
  timeout = options[:timeout] || 0
295
- Resource.new(name, tickets: options[:tickets], quota: options[:quota], permissions: permissions, timeout: timeout)
307
+ ::Semian::Resource.new(name,
308
+ tickets: options[:tickets],
309
+ quota: options[:quota],
310
+ permissions: permissions,
311
+ timeout: timeout)
296
312
  end
297
313
 
298
314
  def require_keys!(required, options)
@@ -304,13 +320,13 @@ module Semian
304
320
  end
305
321
 
306
322
  if Semian.semaphores_enabled?
307
- require 'semian/semian'
323
+ require "semian/semian"
308
324
  else
309
325
  Semian::MAX_TICKETS = 0
310
326
  end
311
327
 
312
328
  if defined? ActiveSupport
313
- ActiveSupport.on_load :active_record do
314
- require 'semian/rails'
329
+ ActiveSupport.on_load(:active_record) do
330
+ require "semian/rails"
315
331
  end
316
332
  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.12.0
4
+ version: 0.13.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Francis
@@ -10,213 +10,20 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2022-04-29 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: rake-compiler
17
- requirement: !ruby/object:Gem::Requirement
18
- requirements:
19
- - - ">="
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - ">="
27
- - !ruby/object:Gem::Version
28
- version: '0'
29
- - !ruby/object:Gem::Dependency
30
- name: rake
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: '0'
36
- type: :development
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- version: '0'
43
- - !ruby/object:Gem::Dependency
44
- name: timecop
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: '0'
50
- type: :development
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - ">="
55
- - !ruby/object:Gem::Version
56
- version: '0'
57
- - !ruby/object:Gem::Dependency
58
- name: minitest
59
- requirement: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- version: '0'
64
- type: :development
65
- prerelease: false
66
- version_requirements: !ruby/object:Gem::Requirement
67
- requirements:
68
- - - ">="
69
- - !ruby/object:Gem::Version
70
- version: '0'
71
- - !ruby/object:Gem::Dependency
72
- name: pry-byebug
73
- requirement: !ruby/object:Gem::Requirement
74
- requirements:
75
- - - ">="
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
- type: :development
79
- prerelease: false
80
- version_requirements: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - ">="
83
- - !ruby/object:Gem::Version
84
- version: '0'
85
- - !ruby/object:Gem::Dependency
86
- name: mysql2
87
- requirement: !ruby/object:Gem::Requirement
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- version: '0'
92
- type: :development
93
- prerelease: false
94
- version_requirements: !ruby/object:Gem::Requirement
95
- requirements:
96
- - - ">="
97
- - !ruby/object:Gem::Version
98
- version: '0'
99
- - !ruby/object:Gem::Dependency
100
- name: redis
101
- requirement: !ruby/object:Gem::Requirement
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: '0'
106
- type: :development
107
- prerelease: false
108
- version_requirements: !ruby/object:Gem::Requirement
109
- requirements:
110
- - - ">="
111
- - !ruby/object:Gem::Version
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
127
- - !ruby/object:Gem::Dependency
128
- name: webrick
129
- requirement: !ruby/object:Gem::Requirement
130
- requirements:
131
- - - ">="
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- requirements:
138
- - - ">="
139
- - !ruby/object:Gem::Version
140
- version: '0'
141
- - !ruby/object:Gem::Dependency
142
- name: toxiproxy
143
- requirement: !ruby/object:Gem::Requirement
144
- requirements:
145
- - - "~>"
146
- - !ruby/object:Gem::Version
147
- version: 1.0.0
148
- type: :development
149
- prerelease: false
150
- version_requirements: !ruby/object:Gem::Requirement
151
- requirements:
152
- - - "~>"
153
- - !ruby/object:Gem::Version
154
- version: 1.0.0
155
- - !ruby/object:Gem::Dependency
156
- name: grpc
157
- requirement: !ruby/object:Gem::Requirement
158
- requirements:
159
- - - ">="
160
- - !ruby/object:Gem::Version
161
- version: '0'
162
- type: :development
163
- prerelease: false
164
- version_requirements: !ruby/object:Gem::Requirement
165
- requirements:
166
- - - ">="
167
- - !ruby/object:Gem::Version
168
- version: '0'
169
- - !ruby/object:Gem::Dependency
170
- name: mocha
171
- requirement: !ruby/object:Gem::Requirement
172
- requirements:
173
- - - ">="
174
- - !ruby/object:Gem::Version
175
- version: '0'
176
- type: :development
177
- prerelease: false
178
- version_requirements: !ruby/object:Gem::Requirement
179
- requirements:
180
- - - ">="
181
- - !ruby/object:Gem::Version
182
- version: '0'
183
- - !ruby/object:Gem::Dependency
184
- name: memory_profiler
185
- requirement: !ruby/object:Gem::Requirement
186
- requirements:
187
- - - ">="
188
- - !ruby/object:Gem::Version
189
- version: '0'
190
- type: :development
191
- prerelease: false
192
- version_requirements: !ruby/object:Gem::Requirement
193
- requirements:
194
- - - ">="
195
- - !ruby/object:Gem::Version
196
- version: '0'
197
- - !ruby/object:Gem::Dependency
198
- name: benchmark-memory
199
- requirement: !ruby/object:Gem::Requirement
200
- requirements:
201
- - - ">="
202
- - !ruby/object:Gem::Version
203
- version: '0'
204
- type: :development
205
- prerelease: false
206
- version_requirements: !ruby/object:Gem::Requirement
207
- requirements:
208
- - - ">="
209
- - !ruby/object:Gem::Version
210
- version: '0'
13
+ date: 2022-08-19 00:00:00.000000000 Z
14
+ dependencies: []
211
15
  description: |2
212
16
  A Ruby C extention that is used to control access to shared resources
213
17
  across process boundaries with SysV semaphores.
214
- email: scott.francis@shopify.com
18
+ email: opensource@shopify.com
215
19
  executables: []
216
20
  extensions:
217
21
  - ext/semian/extconf.rb
218
22
  extra_rdoc_files: []
219
23
  files:
24
+ - CHANGELOG.md
25
+ - LICENSE.md
26
+ - README.md
220
27
  - ext/semian/extconf.rb
221
28
  - ext/semian/resource.c
222
29
  - ext/semian/resource.h
@@ -251,6 +58,9 @@ licenses:
251
58
  - MIT
252
59
  metadata:
253
60
  allowed_push_host: https://rubygems.org
61
+ bug_tracker_uri: https://github.com/Shopify/semian/issues
62
+ changelog_uri: https://github.com/Shopify/semian/blob/master/CHANGELOG.md
63
+ source_code_uri: https://github.com/Shopify/semian
254
64
  post_install_message:
255
65
  rdoc_options: []
256
66
  require_paths:
@@ -266,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
266
76
  - !ruby/object:Gem::Version
267
77
  version: '0'
268
78
  requirements: []
269
- rubygems_version: 3.2.20
79
+ rubygems_version: 3.3.3
270
80
  signing_key:
271
81
  specification_version: 4
272
82
  summary: Bulkheading for Ruby with SysV semaphores