redis_queued_locks 0.0.19 → 0.0.21

Sign up to get free protection for your applications and to get access to all the features.
@@ -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