redis_queued_locks 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 612f9339ffba6231bcfe2277af85e2225346f6166eb5bb77da0f507beaeae888
4
- data.tar.gz: 35229b1d26a17a9c46e39e565d11ec416ca0e173f57360765c064327ffa6390a
3
+ metadata.gz: 7f78a90d3830a3797bfd973b8ce48a879ba8400c3daec8827c0c14c25c650bb3
4
+ data.tar.gz: a8e09fae141ff16d142234a4200c86f05abea787fb627e23b4187dd11fa06086
5
5
  SHA512:
6
- metadata.gz: 1fdb43047ee4b3ac72d28a244ddc9cb4d6b363ff3aa3852b3cc27cbb77ab0a159ef1a45e7eb13f4e4407449fc7b7383e1aac1775f5f739e6ae2e2fcacc5ced46
7
- data.tar.gz: 2fbf7fb572005090140ccc9a972e4d84d5be0b1a9a2154fc37c1b04f2dcf44abb06ec6e530c1fa36be0f7ddb3795615f6d7626a224a9d3f3fe913cbf3362734f
6
+ metadata.gz: fe28a66ec0d028453a0e43f2e140b907a100a70b8a547af8067f45f60392339dd9d0540ef9b8638d0bc9588dd0152f4e21ac488d031170cb872679c7ed4bc34a
7
+ data.tar.gz: 6608fc1f6a9b2b2000254ba0b4a39d5d16c50f9265bcf58c7b138066e08c29c32d31047e3419db09aa0bfda88c09af10111254c3bf2ba35df775248f2d732d63
data/.rubocop.yml CHANGED
@@ -5,7 +5,7 @@ inherit_gem:
5
5
  - lib/rubocop.rspec.yml
6
6
 
7
7
  AllCops:
8
- TargetRubyVersion: 3.2
8
+ TargetRubyVersion: 3.1
9
9
  NewCops: enable
10
10
  Include:
11
11
  - lib/**/*.rb
@@ -33,3 +33,6 @@ Metrics/AbcSize:
33
33
 
34
34
  Metrics/CyclomaticComplexity:
35
35
  Enabled: false
36
+
37
+ Metrics/PerceivedComplexity:
38
+ Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.2.2
1
+ 3.1.2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.1] - 2024-02-26
4
+
5
+ - Still the initial release version;
6
+ - Downgrade the minimal Ruby version requirement from 3.2 to 3.1;
7
+
3
8
  ## [0.0.0] - 2024-02-25
4
9
 
5
10
  - Initial release
data/README.md CHANGED
@@ -1,3 +1,18 @@
1
1
  # RedisQueuedLocks
2
2
 
3
3
  Distributed lock implementation with "lock acquisition queue" capabilities based on the Redis Database.
4
+
5
+ ## Instrumentation events
6
+
7
+ - `"redis_queued_locks.lock_obtained"`
8
+ - the moment when the lock was obtained;
9
+ - payload:
10
+ - `ttl` - `integer`/`milliseconds` - lock ttl;
11
+ - `acq_id` - `string` - lock acquier identifier;
12
+ - `lock_key` - `string` - lock name ;
13
+ - `ts` - `integer`/`epoch` - the time when the lock was obtaiend;
14
+ - `acq_time` - `float`/`milliseconds` - time spent on lock acquiring;
15
+
16
+ ## Todo
17
+
18
+ - CI (github actions);
@@ -29,7 +29,11 @@ module RedisQueuedLocks::Acquier::Release
29
29
  # @since 0.1.0
30
30
  def fully_release_all_locks(redis, batch_size)
31
31
  # Step A: release all queus and their related locks
32
- redis.scan('MATCH', RedisQueuedLocks::Resource::LOCK_QUEUE_PATTERN) do |lock_queue|
32
+ redis.scan(
33
+ 'MATCH',
34
+ RedisQueuedLocks::Resource::LOCK_QUEUE_PATTERN,
35
+ count: batch_size
36
+ ) do |lock_queue|
33
37
  redis.pipelined do |pipeline|
34
38
  pipeline.call('ZREMRANGEBYSCORE', lock_queue, '-inf', '+inf')
35
39
  pipeline.call('EXPIRE', RedisQueuedLocks::Resource.lock_key_from_queue(lock_queue))
@@ -38,7 +42,11 @@ module RedisQueuedLocks::Acquier::Release
38
42
 
39
43
  # Step B: release all locks
40
44
  redis.pipelined do |pipeline|
41
- redis.scan('MATCH', RedisQueuedLocks::Resource::LOCK_PATTERN) do |lock_key|
45
+ redis.scan(
46
+ 'MATCH',
47
+ RedisQueuedLocks::Resource::LOCK_PATTERN,
48
+ count: batch_size
49
+ ) do |lock_key|
42
50
  pipeline.call('EXPIRE', lock_key, '0')
43
51
  end
44
52
  end
@@ -14,7 +14,7 @@ module RedisQueuedLocks::Acquier::Try
14
14
  #
15
15
  # @api private
16
16
  # @since 0.1.0
17
- # rubocop:disable Metrics/MethodLength, Metrics/PerceivedComplexity
17
+ # rubocop:disable Metrics/MethodLength
18
18
  def try_to_lock(redis, lock_key, lock_key_queue, acquier_id, acquier_position, ttl, queue_ttl)
19
19
  # Step X: intermediate invocation results
20
20
  inter_result = nil
@@ -111,13 +111,13 @@ module RedisQueuedLocks::Acquier::Try
111
111
  when result == nil || (result.is_a?(::Array) && result.empty?)
112
112
  # Step 7.b: lock is already acquired durign the acquire race => failed to acquire
113
113
  { ok: false, result: :lock_is_acquired_during_acquire_race }
114
- when result.is_a?(::Array) && result.size == 3 # NOTE: 3 is a count of lock commands
114
+ when result.is_a?(::Array) && result.size == 3 # NOTE: 3 is a count of redis lock commands
115
115
  # TODO:
116
116
  # => (!) analyze the command result and do actions with the depending on it;
117
117
  # => (*) at this moment we accept that all comamnds are completed successfully;
118
118
  # => (!) need to analyze:
119
119
  # 1. zpopmin should return our process (array with <acq_id> and <score>)
120
- # 2. hset should return 2 (lock key is added to the redis db with 2 fields)
120
+ # 2. hset should return 2 (lock key is added to the redis as a hashmap with 2 fields)
121
121
  # 3. pexpire should return 1 (expiration time is successfully applied)
122
122
 
123
123
  # Step 7.c: locked! :) let's go! => successfully acquired
@@ -2,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
+ # rubocop:disable Metrics/ModuleLength
5
6
  module RedisQueuedLocks::Acquier
6
7
  require_relative 'acquier/try'
7
8
  require_relative 'acquier/delay'
@@ -26,6 +27,7 @@ module RedisQueuedLocks::Acquier
26
27
  # @since 0.1.0
27
28
  REDIS_EXPIRATION_DEVIATION = 2 # NOTE: milliseconds
28
29
 
30
+ # rubocop:disable Metrics/ClassLength
29
31
  class << self
30
32
  # @param redis [RedisClient]
31
33
  # Redis connection client.
@@ -47,6 +49,10 @@ module RedisQueuedLocks::Acquier
47
49
  # A time-interval between the each retry (in milliseconds).
48
50
  # @option retry_jitter [Integer]
49
51
  # Time-shift range for retry-delay (in milliseconds).
52
+ # @option raise_errors [Boolean]
53
+ # Raise errors on exceptional cases.
54
+ # @option instrumenter [#notify]
55
+ # See RedisQueuedLocks::Instrument::ActiveSupport for example.
50
56
  # @param [Block]
51
57
  # A block of code that should be executed after the successfully acquired lock.
52
58
  # @return [Hash<Symbol,Any>]
@@ -66,6 +72,8 @@ module RedisQueuedLocks::Acquier
66
72
  retry_count:,
67
73
  retry_delay:,
68
74
  retry_jitter:,
75
+ raise_errors:,
76
+ instrumenter:,
69
77
  &block
70
78
  )
71
79
  # Step 1: prepare lock requirements (generate lock name, calc lock ttl, etc).
@@ -76,11 +84,20 @@ module RedisQueuedLocks::Acquier
76
84
  acquier_position = RedisQueuedLocks::Resource.calc_initial_acquier_position
77
85
 
78
86
  # Step X: intermediate result observer
79
- acq_process = { lock_info: {}, should_try: true, tries: 0, acquired: false, result: nil }
87
+ acq_process = {
88
+ lock_info: {},
89
+ should_try: true,
90
+ tries: 0,
91
+ acquired: false,
92
+ result: nil,
93
+ acq_time: nil # NOTE: in milliseconds
94
+ }
80
95
  acq_dequeue = -> { dequeue_from_lock_queue(redis, lock_key_queue, acquier_id) }
81
96
 
82
97
  # Step 2: try to lock with timeout
83
- with_timeout(timeout, lock_key, on_timeout: acq_dequeue) do
98
+ with_timeout(timeout, lock_key, raise_errors, on_timeout: acq_dequeue) do
99
+ acq_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
100
+
84
101
  # Step 2.1: caclically try to obtain the lock
85
102
  while acq_process[:should_try]
86
103
  try_to_lock(
@@ -93,15 +110,33 @@ module RedisQueuedLocks::Acquier
93
110
  queue_ttl
94
111
  ) => { ok:, result: }
95
112
 
113
+ acq_end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
114
+ acq_time = ((acq_end_time - acq_start_time) * 1_000).ceil
115
+
96
116
  # Step X: save the intermediate results to the result observer
97
117
  acq_process[:result] = result
98
118
 
99
119
  # Step 2.1: analyze an acquirement attempt
100
120
  if ok
121
+ # INSTRUMENT: lock obtained
122
+ instrumenter.notify('redis_queued_locks.lock_obtained', {
123
+ lock_key: result[:lock_key],
124
+ ttl: result[:ttl],
125
+ acq_id: result[:acq_id],
126
+ ts: result[:ts],
127
+ acq_time: acq_time
128
+ })
129
+
101
130
  # Step 2.1.a: successfully acquired => build the result
102
- acq_process[:lock_info] = result
131
+ acq_process[:lock_info] = {
132
+ lock_key: result[:lock_key],
133
+ acq_id: result[:acq_id],
134
+ ts: result[:ts],
135
+ ttl: result[:ttl]
136
+ }
103
137
  acq_process[:acquired] = true
104
138
  acq_process[:should_try] = false
139
+ acq_process[:acq_time] = acq_time
105
140
  else
106
141
  # Step 2.1.b: failed acquirement => retry
107
142
  acq_process[:tries] += 1
@@ -125,7 +160,7 @@ module RedisQueuedLocks::Acquier
125
160
  if acq_process[:acquired]
126
161
  # Step 3.a: acquired successfully => run logic or return the result of acquirement
127
162
  if block_given?
128
- yield_with_expire(redis, lock_key, &block)
163
+ yield_with_expire(redis, lock_key, &block) # INSTRUMENT: lock release
129
164
  else
130
165
  { ok: true, result: acq_process[:lock_info] }
131
166
  end
@@ -154,6 +189,7 @@ module RedisQueuedLocks::Acquier
154
189
  lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
155
190
  lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
156
191
 
192
+ # INSTRUMENT: lock release
157
193
  result = fully_release_lock(redis, lock_key, lock_key_queue)
158
194
  { ok: true, result: result }
159
195
  end
@@ -169,26 +205,37 @@ module RedisQueuedLocks::Acquier
169
205
  # @api private
170
206
  # @since 0.1.0
171
207
  def release_all_locks!(redis, batch_size)
208
+ # INSTRUMENT: all locks released
172
209
  result = fully_release_all_locks(redis, batch_size)
173
210
  { ok: true, result: result }
174
211
  end
175
212
 
176
213
  private
177
214
 
178
- # @param timeout [Integer] Time period after which the logic will fail with timeout error.
179
- # @param lock_key [String] Lock name.
180
- # @option on_timeout [Proc,NilClass] Callback invoked on Timeout::Error.
215
+ # @param timeout [NilClass,Integer]
216
+ # Time period after which the logic will fail with timeout error.
217
+ # @param lock_key [String]
218
+ # Lock name.
219
+ # @param raise_errors [Boolean]
220
+ # Raise erros on exceptional cases.
221
+ # @option on_timeout [Proc,NilClass]
222
+ # Callback invoked on Timeout::Error.
181
223
  # @return [Any]
182
224
  #
183
225
  # @api private
184
226
  # @since 0.1.0
185
- def with_timeout(timeout, lock_key, on_timeout: nil, &block)
227
+ def with_timeout(timeout, lock_key, raise_errors, on_timeout: nil, &block)
186
228
  ::Timeout.timeout(timeout, &block)
187
229
  rescue ::Timeout::Error
188
230
  on_timeout.call unless on_timeout == nil
189
- raise(RedisQueuedLocks::LockAcquiermentTimeoutError, <<~ERROR_MESSAGE.strip)
190
- Failed to acquire the lock "#{lock_key}" for the given timeout (#{timeout} seconds).
191
- ERROR_MESSAGE
231
+
232
+ if raise_errors
233
+ raise(RedisQueuedLocks::LockAcquiermentTimeoutError, <<~ERROR_MESSAGE.strip)
234
+ Failed to acquire the lock "#{lock_key}" for the given timeout (#{timeout} seconds).
235
+ ERROR_MESSAGE
236
+ end
192
237
  end
193
238
  end
239
+ # rubocop:enable Metrics/ClassLength
194
240
  end
241
+ # rubocop:enable Metrics/ModuleLength
@@ -10,23 +10,25 @@ class RedisQueuedLocks::Client
10
10
  setting :retry_count, 3
11
11
  setting :retry_delay, 200 # NOTE: milliseconds
12
12
  setting :retry_jitter, 50 # NOTE: milliseconds
13
- setting :acquire_timeout, 10 # NOTE: seconds
13
+ setting :default_timeout, 10 # NOTE: seconds
14
14
  setting :exp_precision, 1 # NOTE: milliseconds
15
15
  setting :default_lock_ttl, 10_000 # NOTE: milliseconds
16
16
  setting :default_queue_ttl, 5 # NOTE: seconds
17
17
  setting :lock_release_batch_size, 100
18
+ setting :instrumenter, RedisQueuedLocks::Instrument::VoidNotifier
18
19
 
19
20
  # TODO: setting :logger, Logger.new(IO::NULL)
20
21
  # TODO: setting :debug, true/false
21
22
 
22
- validate 'retry_count', :integer
23
- validate 'retry_delay', :integer
24
- validate 'retry_jitter', :integer
25
- validate 'acquire_timeout', :integer
26
- validate 'exp_precision', :integer
27
- validate 'default_lock_tt', :integer
28
- validate 'default_queue_ttl', :integer
29
- validate 'lock_release_batch_size', :integer
23
+ validate('retry_count', :integer)
24
+ validate('retry_delay', :integer)
25
+ validate('retry_jitter', :integer)
26
+ validate('default_timeout', :integer)
27
+ validate('exp_precision', :integer)
28
+ validate('default_lock_tt', :integer)
29
+ validate('default_queue_ttl', :integer)
30
+ validate('lock_release_batch_size', :integer)
31
+ validate('instrumenter') { |instr| RedisQueuedLocks::Instrument.valid_interface?(instr) }
30
32
  end
31
33
 
32
34
  # @return [RedisClient]
@@ -67,6 +69,10 @@ class RedisQueuedLocks::Client
67
69
  # A time-interval between the each retry (in milliseconds).
68
70
  # @option retry_jitter [Integer]
69
71
  # Time-shift range for retry-delay (in milliseconds).
72
+ # @option instrumenter [#notify]
73
+ # See RedisQueuedLocks::Instrument::ActiveSupport for example.
74
+ # @option raise_errors [Boolean]
75
+ # Raise errors on library-related limits such as timeout or failed lock obtain.
70
76
  # @param [Block]
71
77
  # A block of code that should be executed after the successfully acquired lock.
72
78
  # @return [Hash<Symbol,Any>]
@@ -80,10 +86,11 @@ class RedisQueuedLocks::Client
80
86
  thread_id: RedisQueuedLocks::Resource.get_thread_id,
81
87
  ttl: config[:default_lock_ttl],
82
88
  queue_ttl: config[:default_queue_ttl],
83
- timeout: config[:acquire_timeout],
89
+ timeout: config[:default_timeout],
84
90
  retry_count: config[:retry_count],
85
91
  retry_delay: config[:retry_delay],
86
92
  retry_jitter: config[:retry_jitter],
93
+ raise_errors: false,
87
94
  &block
88
95
  )
89
96
  RedisQueuedLocks::Acquier.acquire_lock!(
@@ -97,12 +104,45 @@ class RedisQueuedLocks::Client
97
104
  retry_count:,
98
105
  retry_delay:,
99
106
  retry_jitter:,
107
+ raise_errors:,
108
+ instrumenter: config[:instrumenter],
109
+ &block
110
+ )
111
+ end
112
+
113
+ # @note See #lock method signature.
114
+ #
115
+ # @api public
116
+ # @since 0.1.0
117
+ def lock!(
118
+ lock_name,
119
+ process_id: RedisQueuedLocks::Resource.get_process_id,
120
+ thread_id: RedisQueuedLocks::Resource.get_thread_id,
121
+ ttl: config[:default_lock_ttl],
122
+ queue_ttl: config[:default_queue_ttl],
123
+ timeout: config[:default_timeout],
124
+ retry_count: config[:retry_count],
125
+ retry_delay: config[:retry_delay],
126
+ retry_jitter: config[:retry_jitter],
127
+ &block
128
+ )
129
+ lock(
130
+ lock_name,
131
+ process_id:,
132
+ thread_id:,
133
+ ttl:,
134
+ queue_ttl:,
135
+ timeout:,
136
+ retry_count:,
137
+ retry_delay:,
138
+ retry_jitter:,
139
+ raise_errors: true,
100
140
  &block
101
141
  )
102
142
  end
103
143
 
104
144
  # @param lock_name [String] The lock name that should be released.
105
- # @return [?]
145
+ # @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Symbol/Hash }.
106
146
  #
107
147
  # @api public
108
148
  # @since 0.1.0
@@ -110,7 +150,7 @@ class RedisQueuedLocks::Client
110
150
  RedisQueuedLocks::Acquier.release_lock!(redis_client, lock_name)
111
151
  end
112
152
 
113
- # @return [?]
153
+ # @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Symbol/Hash }.
114
154
  #
115
155
  # @api public
116
156
  # @since 0.1.0
@@ -10,7 +10,7 @@ module RedisQueuedLocks::Debugger
10
10
  # @api private
11
11
  # @since 0.1.0
12
12
  DEBUG_ENABLED_METHOD = <<~METHOD_DECLARATION.strip.freeze
13
- def debug(message) = STDOUT.write_nonblock("#\{message}\n")
13
+ def debug(message) = STDOUT.write("#\{message}\n")
14
14
  METHOD_DECLARATION
15
15
 
16
16
  # @return [String]
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ module RedisQueuedLocks::Instrument::ActiveSupport
6
+ class << self
7
+ # @param event [String]
8
+ # @param payload [Hash<String|Symbol,Any>]
9
+ # @return [void]
10
+ #
11
+ # @api private
12
+ # @since 0.1.0
13
+ def notify(event, payload = {})
14
+ ::ActiveSupport::Notifications.instrument(event, payload)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ module RedisQueuedLocks::Instrument::VoidNotifier
6
+ class << self
7
+ # @param event [String]
8
+ # @param payload [Hash<String|Symbol,Any>]
9
+ # @return [void]
10
+ #
11
+ # @api private
12
+ # @since 0.1.0
13
+ def notify(event, payload = {}); end
14
+ end
15
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ # @api public
4
+ # @since 0.1.0
5
+ module RedisQueuedLocks::Instrument
6
+ require_relative 'instrument/void_notifier'
7
+ require_relative 'instrument/active_support'
8
+
9
+ class << self
10
+ # @param instrumenter [Class,Module,Object]
11
+ # @return [Boolean]
12
+ #
13
+ # @api public
14
+ # @since 0.1.0
15
+ def valid_interface?(instrumenter)
16
+ if instrumenter == RedisQueuedLocks::Instrument::ActiveSupport
17
+ # NOTE: active_support should be required in your app
18
+ defined?(::ActiveSupport::Notifications)
19
+ elsif instrumenter.respond_to?(:notify)
20
+ # NOTE: the method signature should be (event, payload). Supported variants:
21
+ # => [[:req, :event], [:req, :payload]]
22
+ # => [[:req, :event], [:opt, :payload]]
23
+ # => [[:opt, :event], [:opt, :payload]]
24
+
25
+ m_obj = instrumenter.method(:notify)
26
+ m_sig = m_obj.parameters
27
+
28
+ f_prm = m_sig[0][0]
29
+ s_prm = m_sig[1][0]
30
+
31
+ if m_sig.size == 2
32
+ # rubocop:disable Layout/MultilineOperationIndentation
33
+ # NOTE: check the signature vairants
34
+ f_prm == :req && s_prm == :req ||
35
+ f_prm == :req && s_prm == :opt ||
36
+ f_prm == :opt && s_prm == :opt
37
+ # rubocop:enable Layout/MultilineOperationIndentation
38
+ else
39
+ # NOTE: incompatible signature
40
+ false
41
+ end
42
+ else
43
+ # NOTE: no required method :notify
44
+ false
45
+ end
46
+ end
47
+ end
48
+ end
@@ -4,6 +4,6 @@ module RedisQueuedLocks
4
4
  # @return [String]
5
5
  #
6
6
  # @api public
7
- # @since 0.0.0
8
- VERSION = '0.0.0'
7
+ # @since 0.0.1
8
+ VERSION = '0.0.1'
9
9
  end
@@ -12,7 +12,7 @@ module RedisQueuedLocks
12
12
  require_relative 'redis_queued_locks/debugger'
13
13
  require_relative 'redis_queued_locks/resource'
14
14
  require_relative 'redis_queued_locks/acquier'
15
- require_relative 'redis_queued_locks/instrumentation'
15
+ require_relative 'redis_queued_locks/instrument'
16
16
  require_relative 'redis_queued_locks/client'
17
17
 
18
18
  # @since 0.1.0
@@ -3,7 +3,7 @@
3
3
  require_relative 'lib/redis_queued_locks/version'
4
4
 
5
5
  Gem::Specification.new do |spec|
6
- spec.required_ruby_version = '>= 3.2.0'
6
+ spec.required_ruby_version = '>= 3.1'
7
7
 
8
8
  spec.name = 'redis_queued_locks'
9
9
  spec.version = RedisQueuedLocks::VERSION
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_queued_locks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Ibragimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-02-25 00:00:00.000000000 Z
11
+ date: 2024-02-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -64,7 +64,9 @@ files:
64
64
  - lib/redis_queued_locks/debugger.rb
65
65
  - lib/redis_queued_locks/debugger/interface.rb
66
66
  - lib/redis_queued_locks/errors.rb
67
- - lib/redis_queued_locks/instrumentation.rb
67
+ - lib/redis_queued_locks/instrument.rb
68
+ - lib/redis_queued_locks/instrument/active_support.rb
69
+ - lib/redis_queued_locks/instrument/void_notifier.rb
68
70
  - lib/redis_queued_locks/resource.rb
69
71
  - lib/redis_queued_locks/version.rb
70
72
  - redis_queued_locks.gemspec
@@ -83,14 +85,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
83
85
  requirements:
84
86
  - - ">="
85
87
  - !ruby/object:Gem::Version
86
- version: 3.2.0
88
+ version: '3.1'
87
89
  required_rubygems_version: !ruby/object:Gem::Requirement
88
90
  requirements:
89
91
  - - ">="
90
92
  - !ruby/object:Gem::Version
91
93
  version: '0'
92
94
  requirements: []
93
- rubygems_version: 3.5.3
95
+ rubygems_version: 3.5.1
94
96
  signing_key:
95
97
  specification_version: 4
96
98
  summary: Queued distributed locks based on Redis.
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # @api private
4
- # @since 0.1.0
5
- module RedisQueuedLocks::Instrumentation
6
- end