redis_queued_locks 0.0.19 → 0.0.21

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.
@@ -2,557 +2,16 @@
2
2
 
3
3
  # @api private
4
4
  # @since 0.1.0
5
- # rubocop:disable Metrics/ModuleLength
6
5
  module RedisQueuedLocks::Acquier
7
- require_relative 'acquier/try'
8
- require_relative 'acquier/delay'
9
- require_relative 'acquier/yield_expire'
10
- require_relative 'acquier/release'
11
-
12
- # @since 0.1.0
13
- extend Try
14
- # @since 0.1.0
15
- extend Delay
16
- # @since 0.1.0
17
- extend YieldExpire
18
- # @since 0.1.0
19
- extend Release
20
-
21
- # @return [Integer] Redis expiration error in milliseconds.
22
- #
23
- # @api private
24
- # @since 0.1.0
25
- REDIS_EXPIRE_ERROR = 1
26
-
27
- # rubocop:disable Metrics/ClassLength
28
- class << self
29
- # @param redis [RedisClient]
30
- # Redis connection client.
31
- # @param lock_name [String]
32
- # Lock name to be acquier.
33
- # @option process_id [Integer,String]
34
- # The process that want to acquire a lock.
35
- # @option thread_id [Integer,String]
36
- # The process's thread that want to acquire a lock.
37
- # @option fiber_id [Integer,String]
38
- # A current fiber that want to acquire a lock.
39
- # @option ractor_id [Integer,String]
40
- # The current ractor that want to acquire a lock.
41
- # @option ttl [Integer,NilClass]
42
- # Lock's time to live (in milliseconds). Nil means "without timeout".
43
- # @option queue_ttl [Integer]
44
- # Lifetime of the acuier's lock request. In seconds.
45
- # @option timeout [Integer]
46
- # Time period whe should try to acquire the lock (in seconds).
47
- # @option timed [Boolean]
48
- # Limit the invocation time period of the passed block of code by the lock's TTL.
49
- # @option retry_count [Integer,NilClass]
50
- # How many times we should try to acquire a lock. Nil means "infinite retries".
51
- # @option retry_delay [Integer]
52
- # A time-interval between the each retry (in milliseconds).
53
- # @option retry_jitter [Integer]
54
- # Time-shift range for retry-delay (in milliseconds).
55
- # @option raise_errors [Boolean]
56
- # Raise errors on exceptional cases.
57
- # @option instrumenter [#notify]
58
- # See RedisQueuedLocks::Instrument::ActiveSupport for example.
59
- # @option identity [String]
60
- # Unique acquire identifier that is also should be unique between processes and pods
61
- # on different machines. By default the uniq identity string is
62
- # represented as 10 bytes hexstr.
63
- # @option fail_fast [Boolean]
64
- # Should the required lock to be checked before the try and exit immidetly if lock is
65
- # already obtained.
66
- # @param [Block]
67
- # A block of code that should be executed after the successfully acquired lock.
68
- # @return [RedisQueuedLocks::Data,Hash<Symbol,Any>,yield]
69
- # - Format: { ok: true/false, result: Any }
70
- # - If block is given the result of block's yeld will be returned.
71
- #
72
- # @api private
73
- # @since 0.1.0
74
- # rubocop:disable Metrics/MethodLength, Metrics/BlockNesting
75
- def acquire_lock!(
76
- redis,
77
- lock_name,
78
- process_id:,
79
- thread_id:,
80
- fiber_id:,
81
- ractor_id:,
82
- ttl:,
83
- queue_ttl:,
84
- timeout:,
85
- timed:,
86
- retry_count:,
87
- retry_delay:,
88
- retry_jitter:,
89
- raise_errors:,
90
- instrumenter:,
91
- identity:,
92
- fail_fast:,
93
- &block
94
- )
95
- # Step 1: prepare lock requirements (generate lock name, calc lock ttl, etc).
96
- acquier_id = RedisQueuedLocks::Resource.acquier_identifier(
97
- process_id,
98
- thread_id,
99
- fiber_id,
100
- ractor_id,
101
- identity
102
- )
103
- # NOTE:
104
- # - think aobut the redis expiration error
105
- # - (ttl - REDIS_EXPIRE_ERROR).yield_self { |val| (val == 0) ? ttl : val }
106
- lock_ttl = ttl
107
- lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
108
- lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
109
- acquier_position = RedisQueuedLocks::Resource.calc_initial_acquier_position
110
-
111
- # Step X: intermediate result observer
112
- acq_process = {
113
- lock_info: {},
114
- should_try: true,
115
- tries: 0,
116
- acquired: false,
117
- result: nil,
118
- acq_time: nil, # NOTE: in milliseconds
119
- hold_time: nil, # NOTE: in milliseconds
120
- rel_time: nil # NOTE: in milliseconds
121
- }
122
- acq_dequeue = -> { dequeue_from_lock_queue(redis, lock_key_queue, acquier_id) }
123
-
124
- # Step 2: try to lock with timeout
125
- with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: acq_dequeue) do
126
- acq_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
127
-
128
- # Step 2.1: caclically try to obtain the lock
129
- while acq_process[:should_try]
130
- try_to_lock(
131
- redis,
132
- lock_key,
133
- lock_key_queue,
134
- acquier_id,
135
- acquier_position,
136
- lock_ttl,
137
- queue_ttl,
138
- fail_fast
139
- ) => { ok:, result: }
140
-
141
- acq_end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
142
- acq_time = ((acq_end_time - acq_start_time) * 1_000).ceil(2)
143
-
144
- # Step X: save the intermediate results to the result observer
145
- acq_process[:result] = result
146
- acq_process[:acq_end_time] = acq_end_time
147
-
148
- # Step 2.1: analyze an acquirement attempt
149
- if ok
150
- # Step X (instrumentation): lock obtained
151
- instrumenter.notify('redis_queued_locks.lock_obtained', {
152
- lock_key: result[:lock_key],
153
- ttl: result[:ttl],
154
- acq_id: result[:acq_id],
155
- ts: result[:ts],
156
- acq_time: acq_time
157
- })
158
-
159
- # Step 2.1.a: successfully acquired => build the result
160
- acq_process[:lock_info] = {
161
- lock_key: result[:lock_key],
162
- acq_id: result[:acq_id],
163
- ts: result[:ts],
164
- ttl: result[:ttl]
165
- }
166
- acq_process[:acquired] = true
167
- acq_process[:should_try] = false
168
- acq_process[:acq_time] = acq_time
169
- acq_process[:acq_end_time] = acq_end_time
170
- elsif fail_fast && acq_process[:result] == :fail_fast_no_try
171
- acq_process[:should_try] = false
172
- if raise_errors
173
- raise(RedisQueuedLocks::LockAlreadyObtainedError, <<~ERROR_MESSAGE.strip)
174
- Lock "#{lock_key}" is already obtained.
175
- ERROR_MESSAGE
176
- end
177
- else
178
- # Step 2.1.b: failed acquirement => retry
179
- acq_process[:tries] += 1
180
-
181
- if (retry_count != nil && acq_process[:tries] >= retry_count) || fail_fast
182
- # NOTE:
183
- # - reached the retry limit => quit from the loop
184
- # - should fail fast => quit from the loop
185
- acq_process[:should_try] = false
186
- acq_process[:result] = fail_fast ? :fail_fast_after_try : :retry_limit_reached
187
-
188
- # NOTE:
189
- # - reached the retry limit => dequeue from the lock queue
190
- # - should fail fast => dequeue from the lock queue
191
- acq_dequeue.call
192
-
193
- # NOTE: check and raise an error
194
- if fail_fast && raise_errors
195
- raise(RedisQueuedLocks::LockAlreadyObtainedError, <<~ERROR_MESSAGE.strip)
196
- Lock "#{lock_key}" is already obtained.
197
- ERROR_MESSAGE
198
- elsif raise_errors
199
- raise(RedisQueuedLocks::LockAcquiermentRetryLimitError, <<~ERROR_MESSAGE.strip)
200
- Failed to acquire the lock "#{lock_key}"
201
- for the given retry_count limit (#{retry_count} times).
202
- ERROR_MESSAGE
203
- end
204
- else
205
- # NOTE:
206
- # delay the exceution in order to prevent chaotic attempts
207
- # and to allow other processes and threads to obtain the lock too.
208
- delay_execution(retry_delay, retry_jitter)
209
- end
210
- end
211
- end
212
- end
213
-
214
- # Step 3: analyze acquirement result
215
- if acq_process[:acquired]
216
- # Step 3.a: acquired successfully => run logic or return the result of acquirement
217
- if block_given?
218
- begin
219
- yield_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
220
- ttl_shift = ((yield_time - acq_process[:acq_end_time]) * 1000).ceil(2)
221
- yield_with_expire(redis, lock_key, timed, ttl_shift, ttl, &block)
222
- ensure
223
- acq_process[:rel_time] = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
224
- acq_process[:hold_time] = (
225
- (acq_process[:rel_time] - acq_process[:acq_end_time]) * 1000
226
- ).ceil(2)
227
-
228
- # Step X (instrumentation): lock_hold_and_release
229
- run_non_critical do
230
- instrumenter.notify('redis_queued_locks.lock_hold_and_release', {
231
- hold_time: acq_process[:hold_time],
232
- ttl: acq_process[:lock_info][:ttl],
233
- acq_id: acq_process[:lock_info][:acq_id],
234
- ts: acq_process[:lock_info][:ts],
235
- lock_key: acq_process[:lock_info][:lock_key],
236
- acq_time: acq_process[:acq_time]
237
- })
238
- end
239
- end
240
- else
241
- RedisQueuedLocks::Data[ok: true, result: acq_process[:lock_info]]
242
- end
243
- else
244
- if acq_process[:result] != :retry_limit_reached &&
245
- acq_process[:result] != :fail_fast_no_try &&
246
- acq_process[:result] != :fail_fast_after_try
247
- # NOTE: we have only two situations if lock is not acquired withou fast-fail flag:
248
- # - time limit is reached
249
- # - retry count limit is reached
250
- # In other cases the lock obtaining time and tries count are infinite.
251
- acq_process[:result] = :timeout_reached
252
- end
253
- # Step 3.b: lock is not acquired (acquier is dequeued by timeout callback)
254
- RedisQueuedLocks::Data[ok: false, result: acq_process[:result]]
255
- end
256
- end
257
- # rubocop:enable Metrics/MethodLength, Metrics/BlockNesting
258
-
259
- # Release the concrete lock:
260
- # - 1. clear lock queue: al; related processes released
261
- # from the lock aquierment and should retry;
262
- # - 2. delete the lock: drop lock key from Redis;
263
- # It is safe because the lock obtain logic is transactional and
264
- # watches the original lock for changes.
265
- #
266
- # @param redis [RedisClient]
267
- # Redis connection client.
268
- # @param lock_name [String]
269
- # The lock name that should be released.
270
- # @param isntrumenter [#notify]
271
- # See RedisQueuedLocks::Instrument::ActiveSupport for example.
272
- # @return [RedisQueuedLocks::Data,Hash<Symbol,Any>]
273
- # Format: { ok: true/false, result: Hash<Symbil,Numeric|String> }
274
- #
275
- # @api private
276
- # @since 0.1.0
277
- def release_lock!(redis, lock_name, instrumenter)
278
- lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
279
- lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
280
-
281
- rel_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
282
- fully_release_lock(redis, lock_key, lock_key_queue) => { ok:, result: }
283
- time_at = Time.now.to_i
284
- rel_end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
285
- rel_time = ((rel_end_time - rel_start_time) * 1_000).ceil(2)
286
-
287
- run_non_critical do
288
- instrumenter.notify('redis_queued_locks.explicit_lock_release', {
289
- lock_key: lock_key,
290
- lock_key_queue: lock_key_queue,
291
- rel_time: rel_time,
292
- at: time_at
293
- })
294
- end
295
-
296
- RedisQueuedLocks::Data[
297
- ok: true,
298
- result: { rel_time: rel_time, rel_key: lock_key, rel_queue: lock_key_queue }
299
- ]
300
- end
301
-
302
- # Release all locks:
303
- # - 1. clear all lock queus: drop them all from Redis database by the lock queue pattern;
304
- # - 2. delete all locks: drop lock keys from Redis by the lock key pattern;
305
- #
306
- # @param redis [RedisClient]
307
- # Redis connection client.
308
- # @param batch_size [Integer]
309
- # The number of lock keys that should be released in a time.
310
- # @param isntrumenter [#notify]
311
- # See RedisQueuedLocks::Instrument::ActiveSupport for example.
312
- # @return [RedisQueuedLocks::Data,Hash<Symbol,Any>]
313
- # Format: { ok: true/false, result: Hash<Symbol,Numeric> }
314
- #
315
- # @api private
316
- # @since 0.1.0
317
- def release_all_locks!(redis, batch_size, instrumenter)
318
- rel_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
319
- fully_release_all_locks(redis, batch_size) => { ok:, result: }
320
- time_at = Time.now.to_i
321
- rel_end_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
322
- rel_time = ((rel_end_time - rel_start_time) * 1_000).ceil(2)
323
-
324
- run_non_critical do
325
- instrumenter.notify('redis_queued_locks.explicit_all_locks_release', {
326
- at: time_at,
327
- rel_time: rel_time,
328
- rel_keys: result[:rel_keys]
329
- })
330
- end
331
-
332
- RedisQueuedLocks::Data[
333
- ok: true,
334
- result: { rel_key_cnt: result[:rel_keys], rel_time: rel_time }
335
- ]
336
- end
337
-
338
- # @param redis_client [RedisClient]
339
- # @param lock_name [String]
340
- # @return [Boolean]
341
- #
342
- # @api private
343
- # @since 0.1.0
344
- def locked?(redis_client, lock_name)
345
- lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
346
- redis_client.call('EXISTS', lock_key) == 1
347
- end
348
-
349
- # @param redis_client [RedisClient]
350
- # @param lock_name [String]
351
- # @return [Boolean]
352
- #
353
- # @api private
354
- # @since 0.1.0
355
- def queued?(redis_client, lock_name)
356
- lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
357
- redis_client.call('EXISTS', lock_key_queue) == 1
358
- end
359
-
360
- # @param redis_client [RedisClient]
361
- # @param lock_name [String]
362
- # @return [Hash<Symbol,String|Numeric>,NilClass]
363
- # - `nil` is returned when lock key does not exist or expired;
364
- # - result format: {
365
- # lock_key: "rql:lock:your_lockname", # acquired lock key
366
- # acq_id: "rql:acq:process_id/thread_id", # lock acquier identifier
367
- # ts: 123456789, # <locked at> time stamp (epoch)
368
- # ini_ttl: 123456789, # initial lock key ttl (milliseconds),
369
- # rem_ttl: 123456789, # remaining lock key ttl (milliseconds)
370
- # }
371
- #
372
- # @api private
373
- # @since 0.1.0
374
- def lock_info(redis_client, lock_name)
375
- lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
376
-
377
- result = redis_client.multi(watch: [lock_key]) do |transact|
378
- transact.call('HGETALL', lock_key)
379
- transact.call('PTTL', lock_key)
380
- end
381
-
382
- if result == nil
383
- # NOTE:
384
- # - nil result means that during transaction invocation the lock is changed (CAS):
385
- # - lock is expired;
386
- # - lock is released;
387
- # - lock is expired + re-obtained;
388
- nil
389
- else
390
- hget_cmd_res = result[0]
391
- pttl_cmd_res = result[1]
392
-
393
- if hget_cmd_res == {} || pttl_cmd_res == -2 # NOTE: key does not exist
394
- nil
395
- else
396
- # NOTE: the result of MULTI-command is an array of results of each internal command
397
- # - result[0] (HGETALL) (Hash<String,String>)
398
- # - result[1] (PTTL) (Integer)
399
- {
400
- lock_key: lock_key,
401
- acq_id: hget_cmd_res['acq_id'],
402
- ts: Integer(hget_cmd_res['ts']),
403
- ini_ttl: Integer(hget_cmd_res['ini_ttl']),
404
- rem_ttl: ((pttl_cmd_res == -1) ? Infinity : pttl_cmd_res)
405
- }
406
- end
407
- end
408
- end
409
-
410
- # Returns an information about the required lock queue by the lock name. The result
411
- # represnts the ordered lock request queue that is ordered by score (Redis sets) and shows
412
- # lock acquirers and their position in queue. Async nature with redis communcation can lead
413
- # the sitaution when the queue becomes empty during the queue data extraction. So sometimes
414
- # you can receive the lock queue info with empty queue.
415
- #
416
- # @param redis_client [RedisClient]
417
- # @param lock_name [String]
418
- # @return [Hash<Symbol,String|Array<Hash<Symbol,String|Float>>,NilClass]
419
- # - `nil` is returned when lock queue does not exist;
420
- # - result format: {
421
- # lock_queue: "rql:lock_queue:your_lock_name", # lock queue key in redis,
422
- # queue: [
423
- # { acq_id: "rql:acq:process_id/thread_id", score: 123 },
424
- # { acq_id: "rql:acq:process_id/thread_id", score: 456 },
425
- # ] # ordered set (by score) with information about an acquier and their position in queue
426
- # }
427
- #
428
- # @api private
429
- # @since 0.1.0
430
- def queue_info(redis_client, lock_name)
431
- lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
432
-
433
- result = redis_client.pipelined do |pipeline|
434
- pipeline.call('EXISTS', lock_key_queue)
435
- pipeline.call('ZRANGE', lock_key_queue, '0', '-1', 'WITHSCORES')
436
- end
437
-
438
- exists_cmd_res = result[0]
439
- zrange_cmd_res = result[1]
440
-
441
- if exists_cmd_res == 1
442
- # NOTE: queue existed during the piepline invocation
443
- {
444
- lock_queue: lock_key_queue,
445
- queue: zrange_cmd_res.map { |val| { acq_id: val[0], score: val[1] } }
446
- }
447
- else
448
- # NOTE: queue did not exist during the pipeline invocation
449
- nil
450
- end
451
- end
452
-
453
- # @param redis_client [RedisClient]
454
- # @param lock_name [String]
455
- # @param milliseconds [Integer]
456
- # @return [?]
457
- #
458
- # @api private
459
- # @since 0.1.0
460
- def extend_lock_ttl(redis_client, lock_name, milliseconds)
461
- # TODO: realize
462
- end
463
-
464
- # @param redis_client [RedisClient]
465
- # @option scan_size [Integer]
466
- # @return [Set<String>]
467
- #
468
- # @api private
469
- # @since 0.1.0
470
- def locks(redis_client, scan_size:)
471
- Set.new.tap do |lock_keys|
472
- redis_client.scan(
473
- 'MATCH',
474
- RedisQueuedLocks::Resource::LOCK_PATTERN,
475
- count: scan_size
476
- ) do |lock_key|
477
- # TODO: reduce unnecessary iterations
478
- lock_keys.add(lock_key)
479
- end
480
- end
481
- end
482
-
483
- # @param redis_client [RedisClient]
484
- # @param scan_size [Integer]
485
- # @return [Set<String>]
486
- #
487
- # @api private
488
- # @since 0.1.0
489
- def queues(redis_client, scan_size:)
490
- Set.new.tap do |lock_queues|
491
- redis_client.scan(
492
- 'MATCH',
493
- RedisQueuedLocks::Resource::LOCK_QUEUE_PATTERN,
494
- count: scan_size
495
- ) do |lock_queue|
496
- # TODO: reduce unnecessary iterations
497
- lock_queues.add(lock_queue)
498
- end
499
- end
500
- end
501
-
502
- # @param redis_client [RedisClient]
503
- # @option scan_size [Integer]
504
- # @return [Array<String>]
505
- #
506
- # @api private
507
- # @since 0.1.0
508
- def keys(redis_client, scan_size:)
509
- Set.new.tap do |keys|
510
- redis_client.scan(
511
- 'MATCH',
512
- RedisQueuedLocks::Resource::KEY_PATTERN,
513
- count: scan_size
514
- ) do |key|
515
- # TODO: reduce unnecessary iterations
516
- keys.add(key)
517
- end
518
- end
519
- end
520
-
521
- private
522
-
523
- # @param timeout [NilClass,Integer]
524
- # Time period after which the logic will fail with timeout error.
525
- # @param lock_key [String]
526
- # Lock name.
527
- # @param raise_errors [Boolean]
528
- # Raise erros on exceptional cases.
529
- # @option on_timeout [Proc,NilClass]
530
- # Callback invoked on Timeout::Error.
531
- # @return [Any]
532
- #
533
- # @api private
534
- # @since 0.1.0
535
- def with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: nil, &block)
536
- ::Timeout.timeout(timeout, &block)
537
- rescue ::Timeout::Error
538
- on_timeout.call unless on_timeout == nil
539
-
540
- if raise_errors
541
- raise(RedisQueuedLocks::LockAcquiermentTimeoutError, <<~ERROR_MESSAGE.strip)
542
- Failed to acquire the lock "#{lock_key}" for the given timeout (#{timeout} seconds).
543
- ERROR_MESSAGE
544
- end
545
- end
546
-
547
- # @param block [Block]
548
- # @return [Any]
549
- #
550
- # @api private
551
- # @since 0.1.0
552
- def run_non_critical(&block)
553
- yield rescue nil
554
- end
555
- end
556
- # rubocop:enable Metrics/ClassLength
6
+ require_relative 'acquier/acquire_lock'
7
+ require_relative 'acquier/release_lock'
8
+ require_relative 'acquier/release_all_locks'
9
+ require_relative 'acquier/is_locked'
10
+ require_relative 'acquier/is_queued'
11
+ require_relative 'acquier/lock_info'
12
+ require_relative 'acquier/queue_info'
13
+ require_relative 'acquier/locks'
14
+ require_relative 'acquier/queues'
15
+ require_relative 'acquier/keys'
16
+ require_relative 'acquier/extend_lock_ttl'
557
17
  end
558
- # rubocop:enable Metrics/ModuleLength
@@ -92,6 +92,8 @@ class RedisQueuedLocks::Client
92
92
  # already obtained;
93
93
  # - Should the logic exit immidietly after the first try if the lock was obtained
94
94
  # by another process while the lock request queue was initially empty;
95
+ # @option metadata [NilClass,Any]
96
+ # - A custom metadata wich will be passed to the instrumenter's payload with :meta key;
95
97
  # @param block [Block]
96
98
  # A block of code that should be executed after the successfully acquired lock.
97
99
  # @return [RedisQueuedLocks::Data,Hash<Symbol,Any>,yield]
@@ -112,9 +114,10 @@ class RedisQueuedLocks::Client
112
114
  raise_errors: false,
113
115
  fail_fast: false,
114
116
  identity: uniq_identity,
117
+ metadata: nil,
115
118
  &block
116
119
  )
117
- RedisQueuedLocks::Acquier.acquire_lock!(
120
+ RedisQueuedLocks::Acquier::AcquireLock.acquire_lock(
118
121
  redis_client,
119
122
  lock_name,
120
123
  process_id: RedisQueuedLocks::Resource.get_process_id,
@@ -132,6 +135,7 @@ class RedisQueuedLocks::Client
132
135
  instrumenter: config[:instrumenter],
133
136
  identity:,
134
137
  fail_fast:,
138
+ metadata:,
135
139
  &block
136
140
  )
137
141
  end
@@ -151,6 +155,7 @@ class RedisQueuedLocks::Client
151
155
  retry_jitter: config[:retry_jitter],
152
156
  fail_fast: false,
153
157
  identity: uniq_identity,
158
+ metadata: nil,
154
159
  &block
155
160
  )
156
161
  lock(
@@ -165,6 +170,7 @@ class RedisQueuedLocks::Client
165
170
  raise_errors: true,
166
171
  identity:,
167
172
  fail_fast:,
173
+ metadata:,
168
174
  &block
169
175
  )
170
176
  end
@@ -177,7 +183,11 @@ class RedisQueuedLocks::Client
177
183
  # @api public
178
184
  # @since 0.1.0
179
185
  def unlock(lock_name)
180
- RedisQueuedLocks::Acquier.release_lock!(redis_client, lock_name, config[:instrumenter])
186
+ RedisQueuedLocks::Acquier::ReleaseLock.release_lock(
187
+ redis_client,
188
+ lock_name,
189
+ config[:instrumenter]
190
+ )
181
191
  end
182
192
 
183
193
  # @param lock_name [String]
@@ -186,7 +196,7 @@ class RedisQueuedLocks::Client
186
196
  # @api public
187
197
  # @since 0.1.0
188
198
  def locked?(lock_name)
189
- RedisQueuedLocks::Acquier.locked?(redis_client, lock_name)
199
+ RedisQueuedLocks::Acquier::IsLocked.locked?(redis_client, lock_name)
190
200
  end
191
201
 
192
202
  # @param lock_name [String]
@@ -195,7 +205,7 @@ class RedisQueuedLocks::Client
195
205
  # @api public
196
206
  # @since 0.1.0
197
207
  def queued?(lock_name)
198
- RedisQueuedLocks::Acquier.queued?(redis_client, lock_name)
208
+ RedisQueuedLocks::Acquier::IsQueued.queued?(redis_client, lock_name)
199
209
  end
200
210
 
201
211
  # @param lock_name [String]
@@ -204,7 +214,7 @@ class RedisQueuedLocks::Client
204
214
  # @api public
205
215
  # @since 0.1.0
206
216
  def lock_info(lock_name)
207
- RedisQueuedLocks::Acquier.lock_info(redis_client, lock_name)
217
+ RedisQueuedLocks::Acquier::LockInfo.lock_info(redis_client, lock_name)
208
218
  end
209
219
 
210
220
  # @param lock_name [String]
@@ -213,7 +223,7 @@ class RedisQueuedLocks::Client
213
223
  # @api public
214
224
  # @since 0.1.0
215
225
  def queue_info(lock_name)
216
- RedisQueuedLocks::Acquier.queue_info(redis_client, lock_name)
226
+ RedisQueuedLocks::Acquier::QueueInfo.queue_info(redis_client, lock_name)
217
227
  end
218
228
 
219
229
  # @param lock_name [String]
@@ -223,7 +233,7 @@ class RedisQueuedLocks::Client
223
233
  # @api public
224
234
  # @since 0.1.0
225
235
  def extend_lock_ttl(lock_name, milliseconds)
226
- RedisQueuedLocks::Acquier.extend_lock_ttl(redis_client, lock_name)
236
+ RedisQueuedLocks::Acquier::ExtendLockTTL.extend_lock_ttl(redis_client, lock_name)
227
237
  end
228
238
 
229
239
  # @option batch_size [Integer]
@@ -233,7 +243,11 @@ class RedisQueuedLocks::Client
233
243
  # @api public
234
244
  # @since 0.1.0
235
245
  def clear_locks(batch_size: config[:lock_release_batch_size])
236
- RedisQueuedLocks::Acquier.release_all_locks!(redis_client, batch_size, config[:instrumenter])
246
+ RedisQueuedLocks::Acquier::ReleaseAllLocks.release_all_locks(
247
+ redis_client,
248
+ batch_size,
249
+ config[:instrumenter]
250
+ )
237
251
  end
238
252
 
239
253
  # @option scan_size [Integer]
@@ -242,7 +256,7 @@ class RedisQueuedLocks::Client
242
256
  # @api public
243
257
  # @since 0.1.0
244
258
  def locks(scan_size: config[:key_extraction_batch_size])
245
- RedisQueuedLocks::Acquier.locks(redis_client, scan_size:)
259
+ RedisQueuedLocks::Acquier::Locks.locks(redis_client, scan_size:)
246
260
  end
247
261
 
248
262
  # @option scan_size [Integer]
@@ -251,7 +265,7 @@ class RedisQueuedLocks::Client
251
265
  # @api public
252
266
  # @since 0.1.0
253
267
  def queues(scan_size: config[:key_extraction_batch_size])
254
- RedisQueuedLocks::Acquier.queues(redis_client, scan_size:)
268
+ RedisQueuedLocks::Acquier::Queues.queues(redis_client, scan_size:)
255
269
  end
256
270
 
257
271
  # @option scan_size [Integer]
@@ -260,7 +274,7 @@ class RedisQueuedLocks::Client
260
274
  # @api public
261
275
  # @since 0.1.0
262
276
  def keys(scan_size: config[:key_extraction_batch_size])
263
- RedisQueuedLocks::Acquier.keys(redis_client, scan_size:)
277
+ RedisQueuedLocks::Acquier::Keys.keys(redis_client, scan_size:)
264
278
  end
265
279
  end
266
280
  # rubocop:enable Metrics/ClassLength