redis_queued_locks 1.7.0 → 1.8.0

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: cd303479ce60c268e630d4ad770657cbe0223cffcb9990d31a9bb3de92d80843
4
- data.tar.gz: 2a19bfed90da70fa8c49bf069a2acd110d3840eeb78f1f21767416c28e5bc6b7
3
+ metadata.gz: 7f8dd117ee12f1f598da555d02516bb950a2d9640b075a048612726b7a88a6ad
4
+ data.tar.gz: c0a5ac4a4dcb6f3b448dc23ffa8d0e0e13a726d50bdd98fc40193704aa6f967d
5
5
  SHA512:
6
- metadata.gz: 0c2d6c956bfc7227cd45c33c8b983ae759e13bf7149121c272821922d66a4be73b57b344e2042f86d0391acbe92de794013e0a67ce6157b402c6a0ca0a3a1740
7
- data.tar.gz: e00ec46afd8e5d8ebef469c0a5d86a026562f8060e8abc95c4f3e89aa9351dc8961fe2d9d181aa4e8203056c74fb4aa8c4043f925b93a5b477c44541eec5ad9f
6
+ metadata.gz: b35d0ef98da0e1ec2c2368b36064eb0501b45d26aaa1b7204230692a41025583366ce181b85eec09cff2d6fe4e93ec146280db78e08f8cbb232a559b91f6d489
7
+ data.tar.gz: 4776dd89a7bf1e27476877465faf3240988929efe398090fa4b8b4f604a976a861558e6f606278b91c2c95530be6c5205f8245c887befe92a75d4efde31820dc
data/CHANGELOG.md CHANGED
@@ -1,8 +1,16 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.8.0] - 2024-06-13
4
+ ### Added
5
+ - A configurable option that enables the adding additional lock/queue data to "Acquirement Timeout"-related error messages for better debugging;
6
+ - Configurable option is used beacuse of the extra error data requires some additional Redis requests that can be costly for memory/cpu/etc resources;
7
+ - An ability to get the current acquirer id (`RedisQueuedLocks::Client#current_acquirer_id`);
8
+ ### Changed
9
+ - Added additional lock information to some exceptions that does not require extra Redis requests;
10
+
3
11
  ## [1.7.0] - 2024-06-12
4
12
  ### Added
5
- - New feature: **Lock Access Strategy**: you can obtain a lock in different ways: `queued` (classic queued FIFO), `random` (get the lock immideatly if lock is free), and soon: `lifo` and `barrier`;
13
+ - New feature: **Lock Access Strategy**: you can obtain a lock in different ways: `queued` (classic queued FIFO), `random` (get the lock immideatly if lock is free):
6
14
  - `:queued` is used by default (classic `redis_queued_locks` behavior);
7
15
  - `:random`: obtain a lock without checking the positions in the queue => if lock is free to obtain - it will be obtained;
8
16
  ### Changed
data/README.md CHANGED
@@ -34,6 +34,7 @@ Provides flexible invocation flow, parametrized limits (lock request ttl, lock t
34
34
  - [locks_info](#locks_info---get-list-of-locks-with-their-info)
35
35
  - [queues_info](#queues_info---get-list-of-queues-with-their-info)
36
36
  - [clear_dead_requests](#clear_dead_requests)
37
+ - [current_acquirer_id](#current_acquirer_id)
37
38
  - [Lock Access Strategies](#lock-access-strategies)
38
39
  - [queued](#lock-access-strategies)
39
40
  - [random](#lock-access-strategies)
@@ -157,6 +158,29 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
157
158
  # - should be all blocks of code are timed by default;
158
159
  config.is_timed_by_default = false
159
160
 
161
+ # (boolean) (default: false)
162
+ # - When the lock acquirement try reached the acquirement time limit (:timeout option) the
163
+ # `RedisQueuedLocks::LockAcquirementTimeoutError` is raised (when `raise_errors` option
164
+ # of the #lock method is set to `true`). The error message contains the lock key name and
165
+ # the timeout value).
166
+ # - <true> option adds the additional details to the error message:
167
+ # - current lock queue state (you can see which acquirer blocks your request and
168
+ # how much acquirers are in queue);
169
+ # - current lock data stored inside (for example: you can check the current acquirer and
170
+ # the lock meta state if you store some additional data there);
171
+ # - Realized as an option because of the additional lock data requires two additional Redis
172
+ # queries: (1) get the current lock from redis and (2) fetch the lock queue state;
173
+ # - These two additional Redis queries has async nature so you can receive
174
+ # inconsistent data of the lock and of the lock queue in your error emssage because:
175
+ # - required lock can be released after the error moment and before the error message build;
176
+ # - required lock can be obtained by other process after the error moment and
177
+ # before the error message build;
178
+ # - required lock queue can reach a state when the blocking acquirer start to obtain the lock
179
+ # and moved from the lock queue after the error moment and before the error message build;
180
+ # - You should consider the async nature of this error message and should use received data
181
+ # from error message correspondingly;
182
+ config.detailed_acq_timeout_error = false
183
+
160
184
  # (symbol) (default: :queued)
161
185
  # - Defines the way in which the lock should be obitained;
162
186
  # - By default it is configured to obtain a lock in classic `queued` way:
@@ -316,6 +340,7 @@ end
316
340
  - [locks_info](#locks_info---get-list-of-locks-with-their-info)
317
341
  - [queues_info](#queues_info---get-list-of-queues-with-their-info)
318
342
  - [clear_dead_requests](#clear_dead_requests)
343
+ - [current_acquirer_id](#current_acquirer_id)
319
344
 
320
345
  ---
321
346
 
@@ -348,6 +373,7 @@ def lock(
348
373
  access_strategy: config[:default_access_strategy],
349
374
  identity: uniq_identity, # (attr_accessor) calculated during client instantiation via config[:uniq_identifier] proc;
350
375
  meta: nil,
376
+ detailed_acq_timeout_error: config[:detailed_acq_timeout_error],
351
377
  instrument: nil,
352
378
  instrumenter: config[:instrumenter],
353
379
  logger: config[:logger],
@@ -433,6 +459,25 @@ def lock(
433
459
  - A custom metadata wich will be passed to the lock data in addition to the existing data;
434
460
  - Custom metadata can not contain reserved lock data keys (such as `lock_key`, `acq_id`, `ts`, `ini_ttl`, `rem_ttl`);
435
461
  - `nil` by default (means "no metadata");
462
+ - `detailed_acq_timeout_error` - (optional) `[Boolean]`
463
+ - When the lock acquirement try reached the acquirement time limit (:timeout option) the
464
+ `RedisQueuedLocks::LockAcquirementTimeoutError` is raised (when `raise_errors` option
465
+ set to `true`). The error message contains the lock key name and the timeout value).
466
+ - <true> option adds the additional details to the error message:
467
+ - current lock queue state (you can see which acquirer blocks your request and how much acquirers are in queue);
468
+ - current lock data stored inside (for example: you can check the current acquirer and the lock meta state if you store some additional data there);
469
+ - Realized as an option because of the additional lock data requires two additional Redis
470
+ queries: (1) get the current lock from redis and (2) fetch the lock queue state;
471
+ - These two additional Redis queries has async nature so you can receive
472
+ inconsistent data of the lock and of the lock queue in your error emssage because:
473
+ - required lock can be released after the error moment and before the error message build;
474
+ - required lock can be obtained by other process after the error moment and
475
+ before the error message build;
476
+ - required lock queue can reach a state when the blocking acquirer start to obtain the lock
477
+ and moved from the lock queue after the error moment and before the error message build;
478
+ - You should consider the async nature of this error message and should use received data
479
+ from error message correspondingly;
480
+ - pre-configred in `config[:detailed_acq_timeout_error]`;
436
481
  - `logger` - (optional) `[::Logger,#debug]`
437
482
  - Logger object used for loggin internal mutation oeprations and opertioan results / process progress;
438
483
  - pre-configured in `config[:logger]` with void logger `RedisQueuedLocks::Logging::VoidLogger`;
@@ -725,6 +770,7 @@ def lock!(
725
770
  fail_fast: false,
726
771
  identity: uniq_identity,
727
772
  meta: nil,
773
+ detailed_acq_timeout_error: config[:detailed_acq_timeout_error]
728
774
  logger: config[:logger],
729
775
  log_lock_try: config[:log_lock_try],
730
776
  instrument: nil,
@@ -1319,8 +1365,45 @@ rql.clear_dead_requests(dead_ttl: 60 * 60 * 1000) # 1 hour in milliseconds
1319
1365
 
1320
1366
  ---
1321
1367
 
1368
+ #### #current_acquirer_id
1369
+
1370
+ - get the current acquirer identifier in RQL notation that you can use for debugging purposes during the lock analyzation;
1371
+ - acquirer identifier format:
1372
+ ```ruby
1373
+ "rql:acq:#{process_id}/#{thread_id}/#{fiber_id}/#{ractor_id}/#{identity}"
1374
+ ```
1375
+ - because of the moment that `#lock`/`#lock!` gives you a possibility to customize `process_id`,
1376
+ `fiber_id`, `thread_id`, `ractor_id` and `unique identity` identifiers the `#current_acquirer_id` method provides this possibility too;
1377
+
1378
+ Accepts:
1379
+
1380
+ - `process_id:` - (optional) `[Integer,Any]`
1381
+ - `::Process.pid` by default;
1382
+ - `thread_id:` - (optional) `[Integer,Any]`;
1383
+ - `::Thread.current.object_id` by default;
1384
+ - `fiber_id:` - (optional) `[Integer,Any]`;
1385
+ - `::Fiber.current.object_id` by default;
1386
+ - `ractor_id:` - (optional) `[Integer,Any]`;
1387
+ - `::Ractor.current.object_id` by default;
1388
+ - `identity:` - (optional) `[String,Any]`;
1389
+ - this value is calculated once during `RedisQueuedLock::Client` instantiation and stored in `@uniq_identity`;
1390
+ - this value can be accessed from `RedisQueuedLock::Client#uniq_identity`;
1391
+ - [Configuration](#configuration) documentation: see `config[:uniq_identifier]`;
1392
+ - [#lock](#lock---obtain-a-lock) method documentation: see `uniq_identifier`;
1393
+
1394
+ ```ruby
1395
+ rql.current_acquirer_id
1396
+
1397
+ # =>
1398
+ "rql:acq:38529/4500/4520/4360/66093702f24a3129"
1399
+ ```
1400
+
1401
+ ---
1402
+
1322
1403
  ## Lock Access Strategies
1323
1404
 
1405
+ <sup>\[[back to top](#table-of-contents)\]</sup>
1406
+
1324
1407
  - **this documentation section is in progress**;
1325
1408
  - (little details for a context of the current implementation and feautres):
1326
1409
  - defines the way in which the lock should be obitained;
@@ -3,29 +3,63 @@
3
3
  # @api private
4
4
  # @since 1.0.0
5
5
  module RedisQueuedLocks::Acquier::AcquireLock::WithAcqTimeout
6
+ # @param redis [RedisClient]
7
+ # Redis connection manager required for additional data extraction for error message.
6
8
  # @param timeout [NilClass,Integer]
7
9
  # Time period after which the logic will fail with timeout error.
8
10
  # @param lock_key [String]
9
- # Lock name.
11
+ # Lock name in RQL notation (rql:lock:some-lock-name).
12
+ # @param lock_name [String]
13
+ # Original lock name passed by the businessl logic (without RQL notaiton parts).
10
14
  # @param raise_errors [Boolean]
11
15
  # Raise erros on exceptional cases.
16
+ # @param detailed_acq_timeout_error [Boolean]
17
+ # Add additional error data about lock queue and required lock to the timeout error or not.
12
18
  # @option on_timeout [Proc,NilClass]
13
19
  # Callback invoked on Timeout::Error.
14
20
  # @return [Any]
15
21
  #
16
22
  # @api private
17
23
  # @since 1.0.0
18
- def with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: nil, &block)
24
+ # @version 1.8.0
25
+ def with_acq_timeout(
26
+ redis,
27
+ timeout,
28
+ lock_key,
29
+ lock_name,
30
+ raise_errors,
31
+ detailed_acq_timeout_error,
32
+ on_timeout: nil,
33
+ &block
34
+ )
19
35
  ::Timeout.timeout(timeout, &block)
20
36
  rescue ::Timeout::Error
21
37
  on_timeout.call unless on_timeout == nil
22
38
 
23
39
  if raise_errors
24
- raise(
25
- RedisQueuedLocks::LockAcquiermentTimeoutError,
26
- "Failed to acquire the lock \"#{lock_key}\" " \
27
- "for the given timeout (#{timeout} seconds)."
28
- )
40
+ if detailed_acq_timeout_error
41
+ # TODO: rewrite these invocations to separated inner-AcquireLock-related modules
42
+ # in order to remove any dependencies from the other public RQL commands cuz
43
+ # all AcquireLock logic elements should be fully independent from others as a core;
44
+ lock_info = RedisQueuedLocks::Acquier::LockInfo.lock_info(redis, lock_name)
45
+ queue_info = RedisQueuedLocks::Acquier::QueueInfo.queue_info(redis, lock_name)
46
+
47
+ # rubocop:disable Metrics/BlockNesting
48
+ raise(
49
+ RedisQueuedLocks::LockAcquiermentTimeoutError,
50
+ "Failed to acquire the lock \"#{lock_key}\" " \
51
+ "for the given <#{timeout} seconds> timeout. Details: " \
52
+ "<Lock Data> => #{lock_info ? lock_info.inspect : '<no_data>'}; " \
53
+ "<Queue Data> => #{queue_info ? queue_info.inspect : '<no_data>'};"
54
+ )
55
+ # rubocop:enable Metrics/BlockNesting
56
+ else
57
+ raise(
58
+ RedisQueuedLocks::LockAcquiermentTimeoutError,
59
+ "Failed to acquire the lock \"#{lock_key}\" " \
60
+ "for the given <#{timeout} seconds> timeout."
61
+ )
62
+ end
29
63
  end
30
64
  end
31
65
  end
@@ -25,6 +25,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
25
25
  # @param ttl [Integer,NilClass] Lock's time to live (in ms). Nil means "without timeout".
26
26
  # @param queue_ttl [Integer] Lock request lifetime.
27
27
  # @param block [Block] Custom logic that should be invoked unter the obtained lock.
28
+ # @param meta [NilClass,Hash<String|Symbol,Any>] Custom metadata wich is passed to the lock data;
28
29
  # @param log_sampled [Boolean] Should the logic be logged or not.
29
30
  # @param instr_sampled [Boolean] Should the logic be instrumented or not.
30
31
  # @param should_expire [Boolean] Should the lock be expired after the block invocation.
@@ -35,7 +36,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
35
36
  #
36
37
  # @api private
37
38
  # @since 1.3.0
38
- # @version 1.7.0
39
+ # @version 1.8.0
39
40
  # rubocop:disable Metrics/MethodLength
40
41
  def yield_expire(
41
42
  redis,
@@ -47,6 +48,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
47
48
  ttl_shift,
48
49
  ttl,
49
50
  queue_ttl,
51
+ meta,
50
52
  log_sampled,
51
53
  instr_sampled,
52
54
  should_expire,
@@ -62,7 +64,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
62
64
  end
63
65
 
64
66
  if timed && ttl != nil
65
- yield_with_timeout(timeout, lock_key, ttl, &block)
67
+ yield_with_timeout(timeout, lock_key, ttl, acquier_id, meta, &block)
66
68
  else
67
69
  yield
68
70
  end
@@ -97,18 +99,24 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
97
99
  # @param timeout [Float]
98
100
  # @parma lock_key [String]
99
101
  # @param lock_ttl [Integer,NilClass]
102
+ # @param acquier_id [String]
103
+ # @param meta [NilClass,Hash<Symbol|String,Any>]
100
104
  # @param block [Blcok]
101
105
  # @return [Any]
102
106
  #
103
107
  # @api private
104
108
  # @since 1.3.0
105
- def yield_with_timeout(timeout, lock_key, lock_ttl, &block)
109
+ # @version 1.8.0
110
+ def yield_with_timeout(timeout, lock_key, lock_ttl, acquier_id, meta, &block)
106
111
  ::Timeout.timeout(timeout, &block)
107
112
  rescue ::Timeout::Error
108
113
  raise(
109
114
  RedisQueuedLocks::TimedLockTimeoutError,
110
- "Passed <timed> block of code exceeded " \
111
- "the lock TTL (lock: \"#{lock_key}\", ttl: #{lock_ttl})"
115
+ "Passed <timed> block of code exceeded the lock TTL " \
116
+ "(lock: \"#{lock_key}\", " \
117
+ "ttl: #{lock_ttl}, " \
118
+ "meta: #{meta ? meta.inspect : '<no-meta>'}, " \
119
+ "acq_id: \"#{acquier_id}\")"
112
120
  )
113
121
  end
114
122
  end
@@ -69,6 +69,10 @@ module RedisQueuedLocks::Acquier::AcquireLock
69
69
  # @option meta [NilClass,Hash<String|Symbol,Any>]
70
70
  # - A custom metadata wich will be passed to the lock data in addition to the existing data;
71
71
  # - Metadata can not contain reserved lock data keys;
72
+ # @option detailed_acq_timeout_error [Boolean]
73
+ # - Add additional data to the acquirement timeout error such as the current lock queue state
74
+ # and the required lock state;
75
+ # - See `config[:detailed_acq_timeout_error]` for details;
72
76
  # @option logger [::Logger,#debug]
73
77
  # - Logger object used from the configuration layer (see config[:logger]);
74
78
  # - See `RedisQueuedLocks::Logging::VoidLogger` for example;
@@ -143,7 +147,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
143
147
  #
144
148
  # @api private
145
149
  # @since 1.0.0
146
- # @version 1.7.0
150
+ # @version 1.8.0
147
151
  def acquire_lock(
148
152
  redis,
149
153
  lock_name,
@@ -163,6 +167,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
163
167
  identity:,
164
168
  fail_fast:,
165
169
  meta:,
170
+ detailed_acq_timeout_error:,
166
171
  instrument:,
167
172
  logger:,
168
173
  log_lock_try:,
@@ -246,7 +251,8 @@ module RedisQueuedLocks::Acquier::AcquireLock
246
251
 
247
252
  acq_dequeue = proc do
248
253
  dequeue_from_lock_queue(
249
- redis, logger,
254
+ redis,
255
+ logger,
250
256
  lock_key,
251
257
  lock_key_queue,
252
258
  queue_ttl,
@@ -263,7 +269,15 @@ module RedisQueuedLocks::Acquier::AcquireLock
263
269
  )
264
270
 
265
271
  # Step 2: try to lock with timeout
266
- with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: acq_dequeue) do
272
+ with_acq_timeout(
273
+ redis,
274
+ timeout,
275
+ lock_key,
276
+ lock_name,
277
+ raise_errors,
278
+ detailed_acq_timeout_error,
279
+ on_timeout: acq_dequeue
280
+ ) do
267
281
  acq_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC, :microsecond)
268
282
 
269
283
  # Step 2.1: cyclically try to obtain the lock
@@ -455,6 +469,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
455
469
  ttl_shift,
456
470
  ttl,
457
471
  queue_ttl,
472
+ meta,
458
473
  log_sampled,
459
474
  instr_sampled,
460
475
  should_expire, # NOTE: should expire the lock after the block execution
@@ -14,6 +14,7 @@ class RedisQueuedLocks::Client
14
14
  setting :try_to_lock_timeout, 10 # NOTE: in seconds
15
15
  setting :default_lock_ttl, 5_000 # NOTE: in milliseconds
16
16
  setting :default_queue_ttl, 15 # NOTE: in seconds
17
+ setting :detailed_acq_timeout_error, false
17
18
  setting :lock_release_batch_size, 100
18
19
  setting :key_extraction_batch_size, 500
19
20
  setting :instrumenter, RedisQueuedLocks::Instrument::VoidNotifier
@@ -37,6 +38,7 @@ class RedisQueuedLocks::Client
37
38
  validate('try_to_lock_timeout') { |val| val == nil || (val.is_a?(::Integer) && val >= 0) }
38
39
  validate('default_lock_tt', :integer)
39
40
  validate('default_queue_ttl', :integer)
41
+ validate('detailed_acq_timeout_error', :boolean)
40
42
  validate('lock_release_batch_size', :integer)
41
43
  validate('instrumenter') { |val| RedisQueuedLocks::Instrument.valid_interface?(val) }
42
44
  validate('uniq_identifier', :proc)
@@ -95,6 +97,39 @@ class RedisQueuedLocks::Client
95
97
  @redis_client = redis_client
96
98
  end
97
99
 
100
+ # Retrun the current acquirer identifier.
101
+ #
102
+ # @option process_id [Integer,Any] Process identifier.
103
+ # @option thread_id [Integer,Any] Thread identifier.
104
+ # @option fiber_id [Integer,Any] Fiber identifier.
105
+ # @option ractor_id [Integer,Any] Ractor identifier.
106
+ # @option identity [String] Unique per-process string. See `config[:uniq_identifier]`.
107
+ # @return [String]
108
+ #
109
+ # @see RedisQueuedLocks::Resource.get_process_id
110
+ # @see RedisQueuedLocks::Resource.get_thread_id
111
+ # @see RedisQueuedLocks::Resource.get_fiber_id
112
+ # @see RedisQueuedLocks::Resource.get_ractor_id
113
+ # @see RedisQueuedLocks::Client#uniq_identity
114
+ #
115
+ # @api public
116
+ # @since 1.8.0
117
+ def current_acquier_id(
118
+ process_id: RedisQueuedLocks::Resource.get_process_id,
119
+ thread_id: RedisQueuedLocks::Resource.get_thread_id,
120
+ fiber_id: RedisQueuedLocks::Resource.get_fiber_id,
121
+ ractor_id: RedisQueuedLocks::Resource.get_ractor_id,
122
+ identity: uniq_identity
123
+ )
124
+ RedisQueuedLocks::Resource.acquier_identifier(
125
+ process_id,
126
+ thread_id,
127
+ fiber_id,
128
+ ractor_id,
129
+ identity
130
+ )
131
+ end
132
+
98
133
  # @param lock_name [String]
99
134
  # Lock name to be obtained.
100
135
  # @option ttl [Integer]
@@ -146,6 +181,27 @@ class RedisQueuedLocks::Client
146
181
  # @option meta [NilClass,Hash<String|Symbol,Any>]
147
182
  # - A custom metadata wich will be passed to the lock data in addition to the existing data;
148
183
  # - Metadata can not contain reserved lock data keys;
184
+ # @option detailed_acq_timeout_error [Boolean]
185
+ # - When the lock acquirement try reached the acquirement time limit (:timeout option) the
186
+ # `RedisQueuedLocks::LockAcquirementTimeoutError` is raised (when `raise_errors` option
187
+ # set to `true`). The error message contains the lock key name and the timeout value).
188
+ # - <true> option adds the additional details to the error message:
189
+ # - current lock queue state (you can see which acquirer blocks your request and
190
+ # how much acquirers are in queue);
191
+ # - current lock data stored inside (for example: you can check the current acquirer and
192
+ # the lock meta state if you store some additional data there);
193
+ # - Realized as an option because of the additional lock data requires two additional Redis
194
+ # queries: (1) get the current lock from redis and (2) fetch the lock queue state;
195
+ # - These two additional Redis queries has async nature so you can receive
196
+ # inconsistent data of the lock and of the lock queue in your error emssage because:
197
+ # - required lock can be released after the error moment and before the error message build;
198
+ # - required lock can be obtained by other process after the error moment and
199
+ # before the error message build;
200
+ # - required lock queue can reach a state when the blocking acquirer start to obtain the lock
201
+ # and moved from the lock queue after the error moment and before the error message build;
202
+ # - You should consider the async nature of this error message and should use received data
203
+ # from error message correspondingly;
204
+ # - pre-configred in `config[:detailed_acq_timeout_error]`;
149
205
  # @option logger [::Logger,#debug]
150
206
  # - Logger object used from the configuration layer (see config[:logger]);
151
207
  # - See `RedisQueuedLocks::Logging::VoidLogger` for example;
@@ -206,7 +262,7 @@ class RedisQueuedLocks::Client
206
262
  #
207
263
  # @api public
208
264
  # @since 1.0.0
209
- # @version 1.7.0
265
+ # @version 1.8.0
210
266
  # rubocop:disable Metrics/MethodLength
211
267
  def lock(
212
268
  lock_name,
@@ -223,6 +279,7 @@ class RedisQueuedLocks::Client
223
279
  access_strategy: config[:default_access_strategy],
224
280
  identity: uniq_identity,
225
281
  meta: nil,
282
+ detailed_acq_timeout_error: config[:detailed_acq_timeout_error],
226
283
  logger: config[:logger],
227
284
  log_lock_try: config[:log_lock_try],
228
285
  instrumenter: config[:instrumenter],
@@ -256,6 +313,7 @@ class RedisQueuedLocks::Client
256
313
  conflict_strategy:,
257
314
  access_strategy:,
258
315
  meta:,
316
+ detailed_acq_timeout_error:,
259
317
  logger:,
260
318
  log_lock_try:,
261
319
  instrument:,
@@ -274,7 +332,7 @@ class RedisQueuedLocks::Client
274
332
  #
275
333
  # @api public
276
334
  # @since 1.0.0
277
- # @version 1.7.0
335
+ # @version 1.8.0
278
336
  # rubocop:disable Metrics/MethodLength
279
337
  def lock!(
280
338
  lock_name,
@@ -291,6 +349,7 @@ class RedisQueuedLocks::Client
291
349
  identity: uniq_identity,
292
350
  instrumenter: config[:instrumenter],
293
351
  meta: nil,
352
+ detailed_acq_timeout_error: config[:detailed_acq_timeout_error],
294
353
  logger: config[:logger],
295
354
  log_lock_try: config[:log_lock_try],
296
355
  instrument: nil,
@@ -317,6 +376,7 @@ class RedisQueuedLocks::Client
317
376
  logger:,
318
377
  log_lock_try:,
319
378
  meta:,
379
+ detailed_acq_timeout_error:,
320
380
  instrument:,
321
381
  instrumenter:,
322
382
  conflict_strategy:,
@@ -5,6 +5,6 @@ module RedisQueuedLocks
5
5
  #
6
6
  # @api public
7
7
  # @since 0.0.1
8
- # @version 1.7.0
9
- VERSION = '1.7.0'
8
+ # @version 1.8.0
9
+ VERSION = '1.8.0'
10
10
  end
@@ -15,21 +15,17 @@ Gem::Specification.new do |spec|
15
15
  'capabilities based on the Redis Database.'
16
16
 
17
17
  spec.description =
18
- 'Distributed locks with "prioritized lock acquisition queue" capabilities ' \
18
+ '|> Distributed locks with "prioritized lock acquisition queue" capabilities ' \
19
19
  'based on the Redis Database. ' \
20
- # ---
21
- 'Each lock request is put into the request queue ' \
22
- "(each lock is hosted by it's own queue separately from other queues) and processed " \
20
+ '|> Each lock request is put into the request queue ' \
21
+ '(each lock is hosted by it\'s own queue separately from other queues) and processed ' \
23
22
  'in order of their priority (FIFO). ' \
24
- # ---
25
- 'Each lock request lives some period of time (RTTL) ' \
23
+ '|> Each lock request lives some period of time (RTTL) ' \
26
24
  '(with requeue capabilities) which guarantees the request queue will never be stacked. ' \
27
- # ---
28
- 'In addition to the classic `queued` (FIFO) strategy RQL supports ' \
25
+ '|> In addition to the classic `queued` (FIFO) strategy RQL supports ' \
29
26
  '`random` (RANDOM) lock obtaining strategy when any acquirer from the lock queue ' \
30
27
  'can obtain the lock regardless the position in the queue. ' \
31
- # ---
32
- 'Provides flexible invocation flow, parametrized limits ' \
28
+ '|> Provides flexible invocation flow, parametrized limits ' \
33
29
  '(lock request ttl, lock ttl, queue ttl, lock attempts limit, fast failing, etc), ' \
34
30
  'logging and instrumentation.'
35
31
 
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: 1.7.0
4
+ version: 1.8.0
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-06-12 00:00:00.000000000 Z
11
+ date: 2024-06-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -38,8 +38,16 @@ dependencies:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.28'
41
- description: 'Distributed locks with "prioritized lock acquisition queue" capabilities
42
- based on the Redis Database. '
41
+ description: '|> Distributed locks with "prioritized lock acquisition queue" capabilities
42
+ based on the Redis Database. |> Each lock request is put into the request queue
43
+ (each lock is hosted by it''s own queue separately from other queues) and processed
44
+ in order of their priority (FIFO). |> Each lock request lives some period of time
45
+ (RTTL) (with requeue capabilities) which guarantees the request queue will never
46
+ be stacked. |> In addition to the classic `queued` (FIFO) strategy RQL supports
47
+ `random` (RANDOM) lock obtaining strategy when any acquirer from the lock queue
48
+ can obtain the lock regardless the position in the queue. |> Provides flexible invocation
49
+ flow, parametrized limits (lock request ttl, lock ttl, queue ttl, lock attempts
50
+ limit, fast failing, etc), logging and instrumentation.'
43
51
  email:
44
52
  - iamdaiver@gmail.com
45
53
  executables: []
@@ -117,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
117
125
  - !ruby/object:Gem::Version
118
126
  version: '0'
119
127
  requirements: []
120
- rubygems_version: 3.3.7
128
+ rubygems_version: 3.5.1
121
129
  signing_key:
122
130
  specification_version: 4
123
131
  summary: Distributed locks with "prioritized lock acquisition queue" capabilities