redis_queued_locks 1.12.0 → 1.13.0

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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +42 -5
  5. data/LICENSE.txt +1 -1
  6. data/README.md +231 -203
  7. data/Rakefile +12 -4
  8. data/Steepfile +16 -0
  9. data/github_ci/ruby3.3.gemfile +17 -0
  10. data/github_ci/ruby3.3.gemfile.lock +217 -0
  11. data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/delay_execution.rb +4 -4
  12. data/lib/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rb +40 -0
  13. data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/dequeue_from_lock_queue.rb +17 -8
  14. data/lib/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rb +166 -0
  15. data/lib/redis_queued_locks/acquirer/acquire_lock/log_visitor.rb +218 -0
  16. data/lib/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rb +543 -0
  17. data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/try_to_lock.rb +126 -92
  18. data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/with_acq_timeout.rb +14 -13
  19. data/lib/redis_queued_locks/acquirer/acquire_lock/yield_expire/log_visitor.rb +76 -0
  20. data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock/yield_expire.rb +43 -20
  21. data/lib/redis_queued_locks/{acquier → acquirer}/acquire_lock.rb +69 -42
  22. data/lib/redis_queued_locks/{acquier → acquirer}/clear_dead_requests.rb +5 -3
  23. data/lib/redis_queued_locks/{acquier → acquirer}/extend_lock_ttl.rb +4 -3
  24. data/lib/redis_queued_locks/{acquier → acquirer}/is_locked.rb +1 -1
  25. data/lib/redis_queued_locks/{acquier → acquirer}/is_queued.rb +1 -1
  26. data/lib/redis_queued_locks/{acquier → acquirer}/keys.rb +5 -5
  27. data/lib/redis_queued_locks/{acquier → acquirer}/lock_info.rb +9 -5
  28. data/lib/redis_queued_locks/{acquier → acquirer}/locks.rb +16 -3
  29. data/lib/redis_queued_locks/{acquier → acquirer}/queue_info.rb +8 -6
  30. data/lib/redis_queued_locks/{acquier → acquirer}/queues.rb +9 -2
  31. data/lib/redis_queued_locks/{acquier → acquirer}/release_all_locks.rb +23 -18
  32. data/lib/redis_queued_locks/{acquier → acquirer}/release_lock.rb +25 -19
  33. data/lib/redis_queued_locks/acquirer.rb +18 -0
  34. data/lib/redis_queued_locks/client.rb +164 -254
  35. data/lib/redis_queued_locks/config/dsl.rb +94 -0
  36. data/lib/redis_queued_locks/config.rb +231 -0
  37. data/lib/redis_queued_locks/data.rb +2 -0
  38. data/lib/redis_queued_locks/errors.rb +27 -11
  39. data/lib/redis_queued_locks/instrument.rb +11 -4
  40. data/lib/redis_queued_locks/logging/void_logger.rb +38 -1
  41. data/lib/redis_queued_locks/logging.rb +20 -5
  42. data/lib/redis_queued_locks/resource.rb +49 -11
  43. data/lib/redis_queued_locks/swarm/acquirers.rb +17 -16
  44. data/lib/redis_queued_locks/swarm/flush_zombies.rb +26 -25
  45. data/lib/redis_queued_locks/swarm/probe_hosts.rb +20 -19
  46. data/lib/redis_queued_locks/swarm/redis_client_builder.rb +3 -3
  47. data/lib/redis_queued_locks/swarm/supervisor.rb +19 -6
  48. data/lib/redis_queued_locks/swarm/swarm_element/isolated.rb +20 -18
  49. data/lib/redis_queued_locks/swarm/swarm_element/threaded.rb +35 -27
  50. data/lib/redis_queued_locks/swarm/zombie_info.rb +9 -9
  51. data/lib/redis_queued_locks/swarm.rb +20 -41
  52. data/lib/redis_queued_locks/utilities/lock.rb +4 -2
  53. data/lib/redis_queued_locks/utilities.rb +2 -2
  54. data/lib/redis_queued_locks/version.rb +2 -2
  55. data/lib/redis_queued_locks.rb +2 -2
  56. data/rbs_collection.lock.yaml +40 -0
  57. data/rbs_collection.yaml +16 -0
  58. data/redis_queued_locks.gemspec +22 -23
  59. data/sig/manifest.yml +7 -0
  60. data/sig/redis_queued_locks/acquier.rbs +4 -0
  61. data/sig/redis_queued_locks/acquirer/acquire_lock/delay_execution.rbs +9 -0
  62. data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rbs +21 -0
  63. data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue.rbs +26 -0
  64. data/sig/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rbs +71 -0
  65. data/sig/redis_queued_locks/acquirer/acquire_lock/log_visitor.rbs +72 -0
  66. data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rbs +179 -0
  67. data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock.rbs +48 -0
  68. data/sig/redis_queued_locks/acquirer/acquire_lock/with_acq_timeout.rbs +19 -0
  69. data/sig/redis_queued_locks/acquirer/acquire_lock/yield_expire.rbs +41 -0
  70. data/sig/redis_queued_locks/acquirer/acquire_lock/yield_with_expire/log_visitor.rbs +32 -0
  71. data/sig/redis_queued_locks/acquirer/acquire_lock.rbs +51 -0
  72. data/sig/redis_queued_locks/acquirer/clear_dead_requests.rbs +28 -0
  73. data/sig/redis_queued_locks/acquirer/extend_lock_ttl.rbs +28 -0
  74. data/sig/redis_queued_locks/acquirer/is_locked.rbs +9 -0
  75. data/sig/redis_queued_locks/acquirer/is_queued.rbs +9 -0
  76. data/sig/redis_queued_locks/acquirer/keys.rbs +10 -0
  77. data/sig/redis_queued_locks/acquirer/lock_info.rbs +10 -0
  78. data/sig/redis_queued_locks/acquirer/locks.rbs +16 -0
  79. data/sig/redis_queued_locks/acquirer/queue_info.rbs +13 -0
  80. data/sig/redis_queued_locks/acquirer/queues.rbs +16 -0
  81. data/sig/redis_queued_locks/acquirer/release_all_locks.rbs +30 -0
  82. data/sig/redis_queued_locks/acquirer/release_lock.rbs +38 -0
  83. data/sig/redis_queued_locks/client.rbs +195 -0
  84. data/sig/redis_queued_locks/config/dsl.rbs +26 -0
  85. data/sig/redis_queued_locks/config.rbs +23 -0
  86. data/sig/redis_queued_locks/data.rbs +4 -0
  87. data/sig/redis_queued_locks/debugger/interface.rbs +9 -0
  88. data/sig/redis_queued_locks/debugger.rbs +13 -0
  89. data/sig/redis_queued_locks/errors.rbs +43 -0
  90. data/sig/redis_queued_locks/instrument/active_support.rbs +7 -0
  91. data/sig/redis_queued_locks/instrument/sampler.rbs +9 -0
  92. data/sig/redis_queued_locks/instrument/void_notifier.rbs +7 -0
  93. data/sig/redis_queued_locks/instrument.rbs +15 -0
  94. data/sig/redis_queued_locks/logging/sampler.rbs +9 -0
  95. data/sig/redis_queued_locks/logging/void_logger.rbs +15 -0
  96. data/sig/redis_queued_locks/logging.rbs +15 -0
  97. data/sig/redis_queued_locks/resource.rbs +42 -0
  98. data/sig/redis_queued_locks/swarm/acquirers.rbs +10 -0
  99. data/sig/redis_queued_locks/swarm/flush_zombies.rbs +13 -0
  100. data/sig/redis_queued_locks/swarm/probe_hosts.rbs +13 -0
  101. data/sig/redis_queued_locks/swarm/redis_client_builder.rbs +19 -0
  102. data/sig/redis_queued_locks/swarm/supervisor.rbs +26 -0
  103. data/sig/redis_queued_locks/swarm/swarm_element/isolated.rbs +52 -0
  104. data/sig/redis_queued_locks/swarm/swarm_element/threaded.rbs +61 -0
  105. data/sig/redis_queued_locks/swarm/swarm_element.rbs +8 -0
  106. data/sig/redis_queued_locks/swarm/zombie_info.rbs +24 -0
  107. data/sig/redis_queued_locks/swarm.rbs +41 -0
  108. data/sig/redis_queued_locks/utilities/lock.rbs +10 -0
  109. data/sig/redis_queued_locks/utilities.rbs +11 -0
  110. data/sig/redis_queued_locks/version.rbs +3 -0
  111. data/sig/redis_queued_locks.rbs +14 -0
  112. data/sig/vendor/active_support.rbs +9 -0
  113. data/sig/vendor/redis_client.rbs +39 -0
  114. data/sig/vendor/semantic_logger.rbs +4 -0
  115. metadata +96 -54
  116. data/lib/redis_queued_locks/acquier/acquire_lock/dequeue_from_lock_queue/log_visitor.rb +0 -40
  117. data/lib/redis_queued_locks/acquier/acquire_lock/instr_visitor.rb +0 -166
  118. data/lib/redis_queued_locks/acquier/acquire_lock/log_visitor.rb +0 -216
  119. data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock/log_visitor.rb +0 -541
  120. data/lib/redis_queued_locks/acquier/acquire_lock/yield_expire/log_visitor.rb +0 -76
  121. data/lib/redis_queued_locks/acquier.rb +0 -18
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # RedisQueuedLocks · ![Gem Version](https://img.shields.io/gem/v/redis_queued_locks) ![build](https://github.com/0exp/redis_queued_locks/actions/workflows/build.yml/badge.svg??branch=master)
1
+ # RedisQueuedLocks · [![Gem Version](https://badge.fury.io/rb/redis_queued_locks.svg)](https://badge.fury.io/rb/redis_queued_locks)
2
+
3
+ [![Tests (RSpec)](https://github.com/0exp/redis_queued_locks/actions/workflows/tests.yml/badge.svg?branch=master)](https://github.com/0exp/redis_queued_locks/actions) [![Lint (Rubocop/RBS)](https://github.com/0exp/redis_queued_locks/actions/workflows/lint.yml/badge.svg?branch=master)](https://github.com/0exp/redis_queued_locks/actions) [![TypeCheck (Runtime) [RBS]](https://github.com/0exp/redis_queued_locks/actions/workflows/typecheck-runtime.yml/badge.svg?branch=master)](https://github.com/0exp/redis_queued_locks/actions) [![TypeCheck (Static) [Steep]](https://github.com/0exp/redis_queued_locks/actions/workflows/typecheck-static.yml/badge.svg?branch=master)](https://github.com/0exp/redis_queued_locks/actions)
2
4
 
3
5
  <a href="https://redis.io/docs/manual/patterns/distributed-locks/">Distributed locks</a> with "prioritized lock acquisition queue" capabilities based on the Redis Database.
4
6
 
@@ -50,7 +52,7 @@ Provides flexible invocation flow, parametrized limits (lock request ttl, lock t
50
52
  - [zombies_info](#zombies_info)
51
53
  - [zombie_locks](#zombie_locks)
52
54
  - [zombie_hosts](#zombie_hosts)
53
- - [zombie_acquiers](#zombie_acquiers)
55
+ - [zombie_acquirers](#zombie_acquirers)
54
56
  - [Lock Access Strategies](#lock-access-strategies)
55
57
  - [queued](#lock-access-strategies)
56
58
  - [random](#lock-access-strategies)
@@ -152,29 +154,29 @@ redis_client = RedisClient.config.new_pool # NOTE: provide your own RedisClient
152
154
  clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
153
155
  # (default: 3) (supports nil)
154
156
  # - nil means "infinite retries" and you are only limited by the "try_to_lock_timeout" config;
155
- config.retry_count = 3
157
+ config['retry_count'] = 3
156
158
 
157
159
  # (milliseconds) (default: 200)
158
- config.retry_delay = 200
160
+ config['retry_delay'] = 200
159
161
 
160
162
  # (milliseconds) (default: 25)
161
- config.retry_jitter = 25
163
+ config['retry_jitter'] = 25
162
164
 
163
165
  # (seconds) (supports nil)
164
166
  # - nil means "no timeout" and you are only limited by "retry_count" config;
165
- config.try_to_lock_timeout = 10
167
+ config['try_to_lock_timeout'] = 10
166
168
 
167
169
  # (milliseconds) (default: 5_000)
168
170
  # - lock's time to live
169
- config.default_lock_ttl = 5_000
171
+ config['default_lock_ttl'] = 5_000
170
172
 
171
173
  # (seconds) (default: 15)
172
174
  # - lock request timeout. after this timeout your lock request in queue will be requeued with new position (at the end of the queue);
173
- config.default_queue_ttl = 15
175
+ config['default_queue_ttl'] = 15
174
176
 
175
177
  # (boolean) (default: false)
176
178
  # - should be all blocks of code are timed by default;
177
- config.is_timed_by_default = false
179
+ config['is_timed_by_default'] = false
178
180
 
179
181
  # (boolean) (default: false)
180
182
  # - When the lock acquirement try reached the acquirement time limit (:timeout option) the
@@ -197,7 +199,7 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
197
199
  # and moved from the lock queue after the error moment and before the error message build;
198
200
  # - You should consider the async nature of this error message and should use received data
199
201
  # from error message correspondingly;
200
- config.detailed_acq_timeout_error = false
202
+ config['detailed_acq_timeout_error'] = false
201
203
 
202
204
  # (symbol) (default: :queued)
203
205
  # - Defines the way in which the lock should be obitained;
@@ -208,7 +210,7 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
208
210
  # - `:queued` (FIFO): the classic queued behavior (default), your lock will be obitaned if you are first in queue and the required lock is free;
209
211
  # - `:random` (RANDOM): obtain a lock without checking the positions in the queue (but with checking the limist,
210
212
  # retries, timeouts and so on). if lock is free to obtain - it will be obtained;
211
- config.default_access_strategy = :queued
213
+ config['default_access_strategy'] = :queued
212
214
 
213
215
  # (symbol) (default: :wait_for_lock)
214
216
  # - Global default conflict strategy mode;
@@ -222,23 +224,23 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
222
224
  # - `:wait_for_lock` - (default) - work in classic way (with timeouts, retry delays, retry limits, etc - in classic way :));
223
225
  # - `:dead_locking` - fail with deadlock exception;
224
226
  # - See "Dead locks and Reentrant Locks" documentation section in REDME.md for details;
225
- config.default_conflict_strategy = :wait_for_lock
227
+ config['default_conflict_strategy'] = :wait_for_lock
226
228
 
227
229
  # (default: 100)
228
230
  # - how many items will be released at a time in #clear_locks and in #clear_dead_requests (uses SCAN);
229
231
  # - affects the performance of your Redis and Ruby Application (configure thoughtfully);
230
- config.lock_release_batch_size = 100
232
+ config['lock_release_batch_size'] = 100
231
233
 
232
234
  # (default: 500)
233
235
  # - how many items should be extracted from redis during the #locks, #queues, #keys
234
236
  # #locks_info, and #queues_info operations (uses SCAN);
235
237
  # - affects the performance of your Redis and Ruby Application (configure thoughtfully;)
236
- config.key_extraction_batch_size = 500
238
+ config['key_extraction_batch_size'] = 500
237
239
 
238
240
  # (default: 1 day)
239
241
  # - the default period of time (in milliseconds) after which a lock request is considered dead;
240
242
  # - used for `#clear_dead_requests` as default vaule of `:dead_ttl` option;
241
- config.dead_request_ttl = (1 * 24 * 60 * 60 * 1000) # one day in milliseconds
243
+ config['dead_request_ttl'] = (1 * 24 * 60 * 60 * 1000) # one day in milliseconds
242
244
 
243
245
  # (default: RedisQueuedLocks::Instrument::VoidNotifier)
244
246
  # - instrumentation layer;
@@ -246,16 +248,16 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
246
248
  # - event: <string> requried;
247
249
  # - payload: <hash> requried;
248
250
  # - disabled by default via `VoidNotifier`;
249
- config.instrumenter = RedisQueuedLocks::Instrument::ActiveSupport
251
+ config['instrumenter'] = RedisQueuedLocks::Instrument::ActiveSupport
250
252
 
251
253
  # (default: -> { RedisQueuedLocks::Resource.calc_uniq_identity })
252
254
  # - uniqude idenfitier that is uniq per process/pod;
253
255
  # - prevents potential lock-acquirement collisions bettween different process/pods
254
- # that have identical process_id/thread_id/fiber_id/ractor_id (identivcal acquier ids);
256
+ # that have identical process_id/thread_id/fiber_id/ractor_id (identivcal acquirer ids);
255
257
  # - it is calculated once per `RedisQueudLocks::Client` instance;
256
258
  # - expects the proc object;
257
259
  # - `SecureRandom.hex(8)` by default;
258
- config.uniq_identifier = -> { RedisQueuedLocks::Resource.calc_uniq_identity }
260
+ config['uniq_identifier'] = -> { RedisQueuedLocks::Resource.calc_uniq_identity }
259
261
 
260
262
  # (default: RedisQueuedLocks::Logging::VoidLogger)
261
263
  # - the logger object;
@@ -264,7 +266,7 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
264
266
  # - at this moment the only debug logs are realised in following cases:
265
267
  # - "[redis_queued_locks.start_lock_obtaining]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
266
268
  # - "[redis_queued_locks.start_try_to_lock_cycle]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
267
- # - "[redis_queued_locks.dead_score_reached__reset_acquier_position]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
269
+ # - "[redis_queued_locks.dead_score_reached__reset_acquirer_position]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
268
270
  # - "[redis_queued_locks.lock_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acq_time", "acs_strat");
269
271
  # - "[redis_queued_locks.extendable_reentrant_lock_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acq_time", "acs_strat");
270
272
  # - "[redis_queued_locks.reentrant_lock_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acq_time", "acs_strat");
@@ -272,7 +274,7 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
272
274
  # - "[redis_queued_locks.expire_lock]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
273
275
  # - "[redis_queued_locks.decrease_lock]" (logs "lock_key", "decreased_ttl", "queue_ttl", "acq_id", "hst_id", "acs_strat");
274
276
  # - by default uses VoidLogger that does nothing;
275
- config.logger = RedisQueuedLocks::Logging::VoidLogger
277
+ config['logger'] = RedisQueuedLocks::Logging::VoidLogger
276
278
 
277
279
  # (default: false)
278
280
  # - adds additional debug logs;
@@ -291,49 +293,49 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
291
293
  # - "[redis_queued_locks.try_lock.exit__no_first]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat", "first_acq_id_in_queue", "<current_lock_data>");
292
294
  # - "[redis_queued_locks.try_lock.exit__lock_still_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat", "first_acq_id_in_queue", "locked_by_acq_id", "<current_lock_data>");
293
295
  # - "[redis_queued_locks.try_lock.obtain__free_to_acquire]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
294
- config.log_lock_try = false
296
+ config['log_lock_try'] = false
295
297
 
296
298
  # (default: false)
297
299
  # - enables <log sampling>: only the configured percent of RQL cases will be logged;
298
300
  # - disabled by default;
299
- # - works in tandem with <config.log_sampling_percent> and <log.sampler> configs;
300
- config.log_sampling_enabled = false
301
+ # - works in tandem with <config['log_sampling_percent']> and <config['log_sampler']> configs;
302
+ config['log_sampling_enabled'] = false
301
303
 
302
304
  # (default: 15)
303
305
  # - the percent of cases that should be logged;
304
- # - take an effect when <config.log_sampling_enalbed> is true;
305
- # - works in tandem with <config.log_sampling_enabled> and <config.log_sampler> configs;
306
- config.log_sampling_percent = 15
306
+ # - take an effect when <config['log_sampling_enalbed']> is true;
307
+ # - works in tandem with <config['log_sampling_enabled']> and <config['log_sampler']> configs;
308
+ config['log_sampling_percent'] = 15
307
309
 
308
310
  # (default: RedisQueuedLocks::Logging::Sampler)
309
311
  # - percent-based log sampler that decides should be RQL case logged or not;
310
- # - works in tandem with <config.log_sampling_enabled> and <config.log_sampling_percent> configs;
312
+ # - works in tandem with <config['log_sampling_enabled']> and <config['log_sampling_percent']> configs;
311
313
  # - based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
312
314
  # method so the algorithm error is ~(0%..13%);
313
315
  # - you can provide your own log sampler with bettter algorithm that should realize
314
316
  # `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Logging::Sampler` for example);
315
- config.log_sampler = RedisQueuedLocks::Logging::Sampler
317
+ config['log_sampler'] = RedisQueuedLocks::Logging::Sampler
316
318
 
317
319
  # (default: false)
318
320
  # - enables <instrumentaion sampling>: only the configured percent of RQL cases will be instrumented;
319
321
  # - disabled by default;
320
- # - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
321
- config.instr_sampling_enabled = false
322
+ # - works in tandem with <config['instr_sampling_percent'] and <config['instr_sampler']>;
323
+ config['nstr_sampling_enabled'] = false
322
324
 
323
325
  # (default: 15)
324
326
  # - the percent of cases that should be instrumented;
325
- # - take an effect when <config.instr_sampling_enalbed> is true;
326
- # - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
327
- config.instr_sampling_percent = 15
327
+ # - take an effect when <config['instr_sampling_enalbed']> is true;
328
+ # - works in tandem with <config['instr_sampling_enabled']> and <config['instr_sampler']> configs;
329
+ config['instr_sampling_percent'] = 15
328
330
 
329
331
  # (default: RedisQueuedLocks::Instrument::Sampler)
330
332
  # - percent-based log sampler that decides should be RQL case instrumented or not;
331
- # - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampling_percent> configs;
333
+ # - works in tandem with <config['instr_sampling_enabled']> and <config['instr_sampling_percent']> configs;
332
334
  # - based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
333
335
  # method so the algorithm error is ~(0%..13%);
334
336
  # - you can provide your own log sampler with bettter algorithm that should realize
335
337
  # `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Instrument::Sampler` for example);
336
- config.instr_sampler = RedisQueuedLocks::Instrument::Sampler
338
+ config['instr_sampler'] = RedisQueuedLocks::Instrument::Sampler
337
339
  end
338
340
  ```
339
341
 
@@ -375,36 +377,36 @@ end
375
377
  - the block's result will be returned;
376
378
  - If block is not passed:
377
379
  - the obtained lock will be released after lock's ttl;
378
- - the lock information will be returned (hash with technical info that contains: lock key, acquier identifier, acquirement timestamp, lock's ttl, type of obtaining process, etc);
380
+ - the lock information will be returned (hash with technical info that contains: lock key, acquirer identifier, acquirement timestamp, lock's ttl, type of obtaining process, etc);
379
381
 
380
382
  ```ruby
381
383
  def lock(
382
384
  lock_name,
383
- ttl: config[:default_lock_ttl],
384
- queue_ttl: config[:default_queue_ttl],
385
- timeout: config[:try_to_lock_timeout],
386
- timed: config[:is_timed_by_default],
387
- retry_count: config[:retry_count],
388
- retry_delay: config[:retry_delay],
389
- retry_jitter: config[:retry_jitter],
385
+ ttl: config['default_lock_ttl'],
386
+ queue_ttl: config['default_queue_ttl'],
387
+ timeout: config['try_to_lock_timeout'],
388
+ timed: config['is_timed_by_default'],
389
+ retry_count: config['retry_count'],
390
+ retry_delay: config['retry_delay'],
391
+ retry_jitter: config['retry_jitter'],
390
392
  raise_errors: false,
391
393
  fail_fast: false,
392
- conflict_strategy: config[:default_conflict_strategy],
393
- access_strategy: config[:default_access_strategy],
394
- identity: uniq_identity, # (attr_accessor) calculated during client instantiation via config[:uniq_identifier] proc;
394
+ conflict_strategy: config['default_conflict_strategy'],
395
+ access_strategy: config['default_access_strategy'],
396
+ identity: uniq_identity, # (attr_accessor) calculated during client instantiation via config['uniq_identifier'] proc;
395
397
  meta: nil,
396
- detailed_acq_timeout_error: config[:detailed_acq_timeout_error],
398
+ detailed_acq_timeout_error: config['detailed_acq_timeout_error'],
397
399
  instrument: nil,
398
- instrumenter: config[:instrumenter],
399
- logger: config[:logger],
400
- log_lock_try: config[:log_lock_try],
401
- log_sampling_enabled: config[:log_sampling_enabled],
402
- log_sampling_percent: config[:log_sampling_percent],
403
- log_sampler: config[:log_sampler],
400
+ instrumenter: config['instrumenter'],
401
+ logger: config['logger'],
402
+ log_lock_try: config['log_lock_try'],
403
+ log_sampling_enabled: config['log_sampling_enabled'],
404
+ log_sampling_percent: config['log_sampling_percent'],
405
+ log_sampler: config['log_sampler'],
404
406
  log_sample_this: false,
405
- instr_sampling_enabled: config[:instr_sampling_enabled],
406
- instr_sampling_percent: config[:instr_sampling_percent],
407
- instr_sampler: config[:instr_sampler],
407
+ instr_sampling_enabled: config['instr_sampling_enabled'],
408
+ instr_sampling_percent: config['instr_sampling_percent'],
409
+ instr_sampler: config['instr_sampler'],
408
410
  instr_sample_this: false,
409
411
  &block
410
412
  )
@@ -414,30 +416,30 @@ def lock(
414
416
  - Lock name to be obtained.
415
417
  - `ttl` - (optional) - [Integer]
416
418
  - Lock's time to live (in milliseconds);
417
- - pre-configured in `config[:default_lock_ttl]`;
419
+ - pre-configured in `config['default_lock_ttl']`;
418
420
  - `queue_ttl` - (optional) `[Integer]`
419
421
  - Lifetime of the acuier's lock request. In seconds.
420
- - pre-configured in `config[:default_queue_ttl]`;
422
+ - pre-configured in `config['default_queue_ttl']`;
421
423
  - `timeout` - (optional) `[Integer,NilClass]`
422
424
  - Time period a client should try to acquire the lock (in seconds). Nil means "without timeout".
423
- - pre-configured in `config[:try_to_lock_timeout]`;
425
+ - pre-configured in `config['try_to_lock_timeout']`;
424
426
  - `timed` - (optiona) `[Boolean]`
425
427
  - Limit the invocation time period of the passed block of code by the lock's TTL.
426
- - pre-configured in `config[:is_timed_by_default]`;
428
+ - pre-configured in `config['is_timed_by_default']`;
427
429
  - `false` by default;
428
430
  - `retry_count` - (optional) `[Integer,NilClass]`
429
431
  - How many times we should try to acquire a lock. Nil means "infinite retries".
430
- - pre-configured in `config[:retry_count]`;
432
+ - pre-configured in `config['retry_count']`;
431
433
  - `retry_delay` - (optional) `[Integer]`
432
434
  - A time-interval between the each retry (in milliseconds).
433
- - pre-configured in `config[:retry_delay]`;
435
+ - pre-configured in `config['retry_delay']`;
434
436
  - `retry_jitter` - (optional) `[Integer]`
435
437
  - Time-shift range for retry-delay (in milliseconds);
436
- - pre-configured in `config[:retry_jitter]`;
438
+ - pre-configured in `config['retry_jitter']`;
437
439
  - `instrumenter` - (optional) `[#notify]`
438
440
  - See RedisQueuedLocks::Instrument::ActiveSupport for example;
439
441
  - See [Instrumentation](#instrumentation) section of docs;
440
- - pre-configured in `config[:isntrumenter]` with void notifier (`RedisQueuedLocks::Instrumenter::VoidNotifier`);
442
+ - pre-configured in `config['isntrumenter']` with void notifier (`RedisQueuedLocks::Instrumenter::VoidNotifier`);
441
443
  - `instrument` - (optional) `[NilClass,Any]`
442
444
  - Custom instrumentation data wich will be passed to the instrumenter's payload with :instrument key;
443
445
  - `nil` by default (means "no custom instrumentation data");
@@ -457,13 +459,13 @@ def lock(
457
459
  - `:queued` (FIFO): (default) the classic queued behavior, your lock will be obitaned if you are first in queue and the required lock is free;
458
460
  - `:random` (RANDOM): obtain a lock without checking the positions in the queue (but with checking the limist, retries, timeouts and so on).
459
461
  if lock is free to obtain - it will be obtained;
460
- - pre-configured in `config[:default_access_strategy]`;
462
+ - pre-configured in `config['default_access_strategy']`;
461
463
  - See [Lock Access Strategies](#lock-access-strategies) documentation section for details;
462
464
  - `conflict_strategy` - (optional) - `[Symbol]`
463
465
  - The conflict strategy mode for cases when the process that obtained the lock
464
466
  want to acquire this lock again;
465
467
  - By default uses `:wait_for_lock` strategy;
466
- - pre-confured in `config[:default_conflict_strategy]`;
468
+ - pre-confured in `config['default_conflict_strategy']`;
467
469
  - Strategies:
468
470
  - `:work_through` - continue working under the lock **without** lock's TTL extension;
469
471
  - `:extendable_work_through` - continue working under the lock **with** lock's TTL extension;
@@ -476,7 +478,7 @@ def lock(
476
478
  pods or/and nodes of your application;
477
479
  - It is calculated once during `RedisQueuedLock::Client` instantiation and stored in `@uniq_identity`
478
480
  ivar (accessed via `uniq_dentity` accessor method);
479
- - Identity calculator is pre-configured in `config[:uniq_identifier]`;
481
+ - Identity calculator is pre-configured in `config['uniq_identifier']`;
480
482
  - `meta` - (optional) `[NilClass,Hash<String|Symbol,Any>]`
481
483
  - A custom metadata wich will be passed to the lock data in addition to the existing data;
482
484
  - Custom metadata can not contain reserved lock data keys (such as `lock_key`, `acq_id`, `ts`, `ini_ttl`, `rem_ttl`);
@@ -499,24 +501,24 @@ def lock(
499
501
  and moved from the lock queue after the error moment and before the error message build;
500
502
  - You should consider the async nature of this error message and should use received data
501
503
  from error message correspondingly;
502
- - pre-configred in `config[:detailed_acq_timeout_error]`;
504
+ - pre-configred in `config['detailed_acq_timeout_error']`;
503
505
  - `logger` - (optional) `[::Logger,#debug]`
504
506
  - Logger object used for loggin internal mutation oeprations and opertioan results / process progress;
505
- - pre-configured in `config[:logger]` with void logger `RedisQueuedLocks::Logging::VoidLogger`;
507
+ - pre-configured in `config['logger']` with void logger `RedisQueuedLocks::Logging::VoidLogger`;
506
508
  - `log_lock_try` - (optional) `[Boolean]`
507
509
  - should be logged the each try of lock acquiring (a lot of logs can be generated depending on your retry configurations);
508
- - pre-configured in `config[:log_lock_try]`;
510
+ - pre-configured in `config['log_lock_try']`;
509
511
  - `false` by default;
510
512
  - `log_sampling_enabled` - (optional) `[Boolean]`
511
513
  - enables **log sampling**: only the configured percent of RQL cases will be logged;
512
514
  - disabled by default;
513
515
  - works in tandem with `log_sampling_percent` and `log_sampler` options;
514
- - pre-configured in `config[:log_sampling_enabled]`;
516
+ - pre-configured in `config['log_sampling_enabled']`;
515
517
  - `log_sampling_percent` - (optional) `[Integer]`
516
518
  - the percent of cases that should be logged;
517
519
  - take an effect when `log_sampling_enalbed` is true;
518
520
  - works in tandem with `log_sampling_enabled` and `log_sampler` options;
519
- - pre-configured in `config[:log_sampling_percent]`;
521
+ - pre-configured in `config['log_sampling_percent']`;
520
522
  - `log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
521
523
  - percent-based log sampler that decides should be RQL case logged or not;
522
524
  - works in tandem with `log_sampling_enabled` and `log_sampling_percent` options;
@@ -524,7 +526,7 @@ def lock(
524
526
  method so the algorithm error is ~(0%..13%);
525
527
  - you can provide your own log sampler with bettter algorithm that should realize
526
528
  `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Logging::Sampler` for example);
527
- - pre-configured in `config[:log_sampler]`;
529
+ - pre-configured in `config['log_sampler']`;
528
530
  - `log_sample_this` - (optional) `[Boolean]`
529
531
  - marks the method that everything should be logged despite the enabled log sampling;
530
532
  - makes sense when log sampling is enabled;
@@ -533,12 +535,12 @@ def lock(
533
535
  - enables **instrumentaion sampling**: only the configured percent of RQL cases will be instrumented;
534
536
  - disabled by default;
535
537
  - works in tandem with `instr_sampling_percent` and `instr_sampler` options;
536
- - pre-configured in `config[:instr_sampling_enabled]`;
538
+ - pre-configured in `config['instr_sampling_enabled']`;
537
539
  - `instr_sampling_percent` - (optional) `[Integer]`
538
540
  - the percent of cases that should be instrumented;
539
541
  - take an effect when `instr_sampling_enalbed` is true;
540
542
  - works in tandem with `instr_sampling_enabled` and `instr_sampler` options;
541
- - pre-configured in `config[:instr_sampling_percent]`;
543
+ - pre-configured in `config['instr_sampling_percent']`;
542
544
  - `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
543
545
  - percent-based log sampler that decides should be RQL case instrumented or not;
544
546
  - works in tandem with `instr_sampling_enabled` and `instr_sampling_percent` options;
@@ -546,7 +548,7 @@ def lock(
546
548
  method so the algorithm error is ~(0%..13%);
547
549
  - you can provide your own log sampler with bettter algorithm that should realize
548
550
  `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Instrument::Sampler` for example);
549
- - pre-configured in `config[:instr_sampler]`;
551
+ - pre-configured in `config['instr_sampler']`;
550
552
  - `instr_sample_this` - (optional) `[Boolean]`
551
553
  - marks the method that everything should be instrumneted despite the enabled instrumentation sampling;
552
554
  - makes sense when instrumentation sampling is enabled;
@@ -594,8 +596,8 @@ Return value:
594
596
  {
595
597
  ok: true,
596
598
  result: {
597
- lock_key: String, # acquierd lock key ("rql:lock:your_lock_name")
598
- acq_id: String, # acquier identifier ("process_id/thread_id/fiber_id/ractor_id/identity")
599
+ lock_key: String, # acquirerd lock key ("rql:lock:your_lock_name")
600
+ acq_id: String, # acquirer identifier ("process_id/thread_id/fiber_id/ractor_id/identity")
599
601
  hst_id: String, # host identifier ("process_id/thread_id/ractor_id/identity")
600
602
  ts: Float, # time (epoch) when lock was obtained (float, Time#to_f)
601
603
  ttl: Integer, # lock's time to live in milliseconds (integer)
@@ -786,37 +788,37 @@ rql.lock('my_lock', retry_delay: 3000, ttl: 3000, access_strategy: :random)
786
788
  - `#lock!` - exceptional lock obtaining;
787
789
  - fails when (and with):
788
790
  - (`RedisQueuedLocks::LockAlreadyObtainedError`) when `fail_fast` is `true` and lock is already obtained;
789
- - (`RedisQueuedLocks::LockAcquiermentTimeoutError`) `timeout` limit reached before lock is obtained;
790
- - (`RedisQueuedLocks::LockAcquiermentRetryLimitError`) `retry_count` limit reached before lock is obtained;
791
+ - (`RedisQueuedLocks::LockAcquirementTimeoutError`) `timeout` limit reached before lock is obtained;
792
+ - (`RedisQueuedLocks::LockAcquirementRetryLimitError`) `retry_count` limit reached before lock is obtained;
791
793
  - (`RedisQueuedLocks::ConflictLockObtainError`) when `conflict_strategy: :dead_locking` is used and the "same-process-dead-lock" is happened (see [Deadlocks and Reentrant locks](#deadlocks-and-reentrant-locks) for details);
792
794
 
793
795
  ```ruby
794
796
  def lock!(
795
797
  lock_name,
796
- ttl: config[:default_lock_ttl],
797
- queue_ttl: config[:default_queue_ttl],
798
- timeout: config[:try_to_lock_timeout],
799
- timed: config[:is_timed_by_default],
800
- retry_count: config[:retry_count],
801
- retry_delay: config[:retry_delay],
802
- retry_jitter: config[:retry_jitter],
798
+ ttl: config['default_lock_ttl'],
799
+ queue_ttl: config['default_queue_ttl'],
800
+ timeout: config['try_to_lock_timeout'],
801
+ timed: config['is_timed_by_default'],
802
+ retry_count: config['retry_count'],
803
+ retry_delay: config['retry_delay'],
804
+ retry_jitter: config['retry_jitter'],
803
805
  fail_fast: false,
804
806
  identity: uniq_identity,
805
807
  meta: nil,
806
- detailed_acq_timeout_error: config[:detailed_acq_timeout_error]
807
- logger: config[:logger],
808
- log_lock_try: config[:log_lock_try],
808
+ detailed_acq_timeout_error: config['detailed_acq_timeout_error']
809
+ logger: config['logger'],
810
+ log_lock_try: config['log_lock_try'],
809
811
  instrument: nil,
810
- instrumenter: config[:instrumenter],
811
- access_strategy: config[:default_access_strategy],
812
- conflict_strategy: config[:default_conflict_strategy],
813
- log_sampling_enabled: config[:log_sampling_enabled],
814
- log_sampling_percent: config[:log_sampling_percent],
815
- log_sampler: config[:log_sampler],
812
+ instrumenter: config['instrumenter'],
813
+ access_strategy: config['default_access_strategy'],
814
+ conflict_strategy: config['default_conflict_strategy'],
815
+ log_sampling_enabled: config['log_sampling_enabled'],
816
+ log_sampling_percent: config['log_sampling_percent'],
817
+ log_sampler: config['log_sampler'],
816
818
  log_sample_this: false,
817
- instr_sampling_enabled: config[:instr_sampling_enabled],
818
- instr_sampling_percent: config[:instr_sampling_percent],
819
- instr_sampler: config[:instr_sampler],
819
+ instr_sampling_enabled: config['instr_sampling_enabled'],
820
+ instr_sampling_percent: config['instr_sampling_percent'],
821
+ instr_sampler: config['instr_sampler'],
820
822
  instr_sample_this: false,
821
823
  &block
822
824
  )
@@ -834,7 +836,7 @@ See `#lock` method [documentation](#lock---obtain-a-lock).
834
836
  - returns `nil` if lock does not exist;
835
837
  - lock data (`Hash<String,String|Integer>`):
836
838
  - `"lock_key"` - `string` - lock key in redis;
837
- - `"acq_id"` - `string` - acquier identifier (process_id/thread_id/fiber_id/ractor_id/identity);
839
+ - `"acq_id"` - `string` - acquirer identifier (process_id/thread_id/fiber_id/ractor_id/identity);
838
840
  - `"hst_id"` - `string` - host identifier (process_id/thread_id/ractor_id/identity);
839
841
  - `"ts"` - `numeric`/`epoch` - the time when lock was obtained;
840
842
  - `"init_ttl"` - `integer` - (milliseconds) initial lock key ttl;
@@ -885,7 +887,7 @@ rql.lock_info("your_lock_name")
885
887
 
886
888
  ```ruby
887
889
  # <for reentrant locks>
888
- # (see `conflict_strategy:` kwarg attribute of #lock/#lock! methods and `config.default_conflict_strategy` config)
890
+ # (see `conflict_strategy:` kwarg attribute of #lock/#lock! methods and `config['default_conflict_strategy']` config)
889
891
 
890
892
  rql.lock("your_lock_name", ttl: 5_000)
891
893
  rql.lock("your_lock_name", ttl: 3_000)
@@ -927,12 +929,12 @@ you can receive the lock queue info with empty queue value (an empty array).
927
929
  - queue represents the ordered set of lock key reqests:
928
930
  - set is ordered by score in ASC manner (inside the Redis Set);
929
931
  - score is represented as a timestamp when the lock request was made;
930
- - represents the acquier identifier and their score as an array of hashes;
932
+ - represents the acquirer identifier and their score as an array of hashes;
931
933
  - returns `nil` if lock queue does not exist;
932
934
  - lock queue data (`Hash<String,String|Array<Hash<String|Numeric>>`):
933
935
  - `"lock_queue"` - `string` - lock queue key in redis;
934
936
  - `"queue"` - `array` - an array of lock requests (array of hashes):
935
- - `"acq_id"` - `string` - acquier identifier (process_id/thread_id/fiber_id/ractor_id/identity by default);
937
+ - `"acq_id"` - `string` - acquirer identifier (process_id/thread_id/fiber_id/ractor_id/identity by default);
936
938
  - `"score"` - `float`/`epoch` - time when the lock request was made (epoch);
937
939
 
938
940
  ```ruby
@@ -987,35 +989,35 @@ rql.queued?("your_lock_name") # => true/false
987
989
  - `lock_name` - (required) `[String]` - the lock name that should be released.
988
990
  - `:logger` - (optional) `[::Logger,#debug]`
989
991
  - custom logger object;
990
- - pre-configured in `config[:logger]`;
992
+ - pre-configured in `config['logger']`;
991
993
  - `:instrumenter` - (optional) `[#notify]`
992
994
  - custom instrumenter object;
993
- - pre-configured in `config[:instrumetner]`;
995
+ - pre-configured in `config['instrumetner']`;
994
996
  - `:instrument` - (optional) `[NilClass,Any]`;
995
997
  - custom instrumentation data wich will be passed to the instrumenter's payload with :instrument key;
996
998
  - `nil` by default (no additional data);
997
999
  - `:log_sampling_enabled` - (optional) `[Boolean]`
998
1000
  - enables **log sampling**;
999
- - pre-configured in `config[:log_sampling_enabled]`;
1001
+ - pre-configured in `config['log_sampling_enabled']`;
1000
1002
  - `:log_sampling_percent` - (optional) `[Integer]`
1001
1003
  - **log sampling**:the percent of cases that should be logged;
1002
- - pre-configured in `config[:log_sampling_percent]`;
1004
+ - pre-configured in `config['log_sampling_percent']`;
1003
1005
  - `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
1004
1006
  - **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
1005
- - pre-configured in `config[:log_sampler]`;
1007
+ - pre-configured in `config['log_sampler']`;
1006
1008
  - `log_sample_this` - (optional) `[Boolean]`
1007
1009
  - marks the method that everything should be logged despite the enabled log sampling;
1008
1010
  - makes sense when log sampling is enabled;
1009
1011
  - `false` by default;
1010
1012
  - `:instr_sampling_enabled` - (optional) `[Boolean]`
1011
1013
  - enables **instrumentaion sampling**;
1012
- - pre-configured in `config[:instr_sampling_enabled]`;
1014
+ - pre-configured in `config['instr_sampling_enabled']`;
1013
1015
  - `instr_sampling_percent` - (optional) `[Integer]`
1014
1016
  - the percent of cases that should be instrumented;
1015
- - pre-configured in `config[:instr_sampling_percent]`;
1017
+ - pre-configured in `config['instr_sampling_percent']`;
1016
1018
  - `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
1017
1019
  - percent-based log sampler that decides should be RQL case instrumented or not;
1018
- - pre-configured in `config[:instr_sampler]`;
1020
+ - pre-configured in `config['instr_sampler']`;
1019
1021
  - `instr_sample_this` - (optional) `[Boolean]`
1020
1022
  - marks the method that everything should be instrumneted despite the enabled instrumentation sampling;
1021
1023
  - makes sense when instrumentation sampling is enabled;
@@ -1062,37 +1064,37 @@ rql.unlock("your_lock_name")
1062
1064
  - accepts:
1063
1065
  - `:batch_size` - (optional) `[Integer]`
1064
1066
  - the size of batch of locks and lock queus that should be cleared under the one pipelined redis command at once;
1065
- - pre-configured in `config[:lock_release_batch_size]`;
1067
+ - pre-configured in `config['lock_release_batch_size']`;
1066
1068
  - `:logger` - (optional) `[::Logger,#debug]`
1067
1069
  - custom logger object;
1068
- - pre-configured value in `config[:logger]`;
1070
+ - pre-configured value in `config['logger']`;
1069
1071
  - `:instrumenter` - (optional) `[#notify]`
1070
1072
  - custom instrumenter object;
1071
- - pre-configured value in `config[:isntrumenter]`;
1073
+ - pre-configured value in `config['isntrumenter']`;
1072
1074
  - `:instrument` - (optional) `[NilClass,Any]`
1073
1075
  - custom instrumentation data wich will be passed to the instrumenter's payload with `:instrument` key;
1074
1076
  - `:log_sampling_enabled` - (optional) `[Boolean]`
1075
1077
  - enables **log sampling**;
1076
- - pre-configured in `config[:log_sampling_enabled]`;
1078
+ - pre-configured in `config['log_sampling_enabled']`;
1077
1079
  - `:log_sampling_percent` - (optional) `[Integer]`
1078
1080
  - **log sampling**:the percent of cases that should be logged;
1079
- - pre-configured in `config[:log_sampling_percent]`;
1081
+ - pre-configured in `config['log_sampling_percent']`;
1080
1082
  - `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
1081
1083
  - **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
1082
- - pre-configured in `config[:log_sampler]`;
1084
+ - pre-configured in `config['log_sampler']`;
1083
1085
  - `log_sample_this` - (optional) `[Boolean]`
1084
1086
  - marks the method that everything should be logged despite the enabled log sampling;
1085
1087
  - makes sense when log sampling is enabled;
1086
1088
  - `false` by default;
1087
1089
  - `:instr_sampling_enabled` - (optional) `[Boolean]`
1088
1090
  - enables **instrumentaion sampling**;
1089
- - pre-configured in `config[:instr_sampling_enabled]`;
1091
+ - pre-configured in `config['instr_sampling_enabled']`;
1090
1092
  - `instr_sampling_percent` - (optional) `[Integer]`
1091
1093
  - the percent of cases that should be instrumented;
1092
- - pre-configured in `config[:instr_sampling_percent]`;
1094
+ - pre-configured in `config['instr_sampling_percent']`;
1093
1095
  - `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
1094
1096
  - percent-based log sampler that decides should be RQL case instrumented or not;
1095
- - pre-configured in `config[:instr_sampler]`;
1097
+ - pre-configured in `config['instr_sampler']`;
1096
1098
  - `instr_sample_this` - (optional) `[Boolean]`
1097
1099
  - marks the method that everything should be instrumneted despite the enabled instrumentation sampling;
1098
1100
  - makes sense when instrumentation sampling is enabled;
@@ -1131,35 +1133,35 @@ rql.clear_locks
1131
1133
  - how many milliseconds should be added to the lock's TTL;
1132
1134
  - `:instrumenter` - (optional) `[#notify]`
1133
1135
  - custom instrumenter object;
1134
- - pre-configured in `config[:instrumetner]`;
1136
+ - pre-configured in `config['instrumetner']`;
1135
1137
  - `:instrument` - (optional) `[NilClass,Any]`;
1136
1138
  - custom instrumentation data wich will be passed to the instrumenter's payload with :instrument key;
1137
1139
  - `nil` by default (no additional data);
1138
1140
  - `:logger` - (optional) `[::Logger,#debug]`
1139
1141
  - custom logger object;
1140
- - pre-configured in `config[:logger]`;
1142
+ - pre-configured in `config['logger']`;
1141
1143
  - `:log_sampling_enabled` - (optional) `[Boolean]`
1142
1144
  - enables **log sampling**;
1143
- - pre-configured in `config[:log_sampling_enabled]`;
1145
+ - pre-configured in `config['log_sampling_enabled']`;
1144
1146
  - `:log_sampling_percent` - (optional) `[Integer]`
1145
1147
  - **log sampling**:the percent of cases that should be logged;
1146
- - pre-configured in `config[:log_sampling_percent]`;
1148
+ - pre-configured in `config['log_sampling_percent']`;
1147
1149
  - `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
1148
1150
  - **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
1149
- - pre-configured in `config[:log_sampler]`;
1151
+ - pre-configured in `config['log_sampler']`;
1150
1152
  - `log_sample_this` - (optional) `[Boolean]`
1151
1153
  - marks the method that everything should be logged despite the enabled log sampling;
1152
1154
  - makes sense when log sampling is enabled;
1153
1155
  - `false` by default;
1154
1156
  - `:instr_sampling_enabled` - (optional) `[Boolean]`
1155
1157
  - enables **instrumentaion sampling**;
1156
- - pre-configured in `config[:instr_sampling_enabled]`;
1158
+ - pre-configured in `config['instr_sampling_enabled']`;
1157
1159
  - `instr_sampling_percent` - (optional) `[Integer]`
1158
1160
  - the percent of cases that should be instrumented;
1159
- - pre-configured in `config[:instr_sampling_percent]`;
1161
+ - pre-configured in `config['instr_sampling_percent']`;
1160
1162
  - `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
1161
1163
  - percent-based log sampler that decides should be RQL case instrumented or not;
1162
- - pre-configured in `config[:instr_sampler]`;
1164
+ - pre-configured in `config['instr_sampler']`;
1163
1165
  - `instr_sample_this` - (optional) `[Boolean]`
1164
1166
  - marks the method that everything should be instrumneted despite the enabled instrumentation sampling;
1165
1167
  - makes sense when instrumentation sampling is enabled;
@@ -1199,7 +1201,7 @@ rql.extend_lock_ttl("my_lock", 5_000) # NOTE: add 5_000 milliseconds
1199
1201
  - get list of obtained locks;
1200
1202
  - uses redis `SCAN` under the hood;
1201
1203
  - accepts:
1202
- - `:scan_size` - `Integer` - (`config[:key_extraction_batch_size]` by default);
1204
+ - `:scan_size` - `Integer` - (`config['key_extraction_batch_size']` by default);
1203
1205
  - `:with_info` - `Boolean` - `false` by default (for details see [#locks_info](#locks_info---get-list-of-locks-with-their-info));
1204
1206
  - returns:
1205
1207
  - `Set<String>` (for `with_info: false`);
@@ -1232,7 +1234,7 @@ rql.locks # or rql.locks(scan_size: 123)
1232
1234
  - get list of lock request queues;
1233
1235
  - uses redis `SCAN` under the hood;
1234
1236
  - accepts
1235
- - `:scan_size` - `Integer` - (`config[:key_extraction_batch_size]` by default);
1237
+ - `:scan_size` - `Integer` - (`config['key_extraction_batch_size']` by default);
1236
1238
  - `:with_info` - `Boolean` - `false` by default (for details see [#queues_info](#queues_info---get-list-of-queues-with-their-info));
1237
1239
  - returns:
1238
1240
  - `Set<String>` (for `with_info: false`);
@@ -1265,7 +1267,7 @@ rql.queues # or rql.queues(scan_size: 123)
1265
1267
  - get list of taken locks and queues;
1266
1268
  - uses redis `SCAN` under the hood;
1267
1269
  - accepts:
1268
- `:scan_size` - `Integer` - (`config[:key_extraction_batch_size]` by default);
1270
+ `:scan_size` - `Integer` - (`config['key_extraction_batch_size']` by default);
1269
1271
  - returns: `Set<String>`
1270
1272
 
1271
1273
  ```ruby
@@ -1298,7 +1300,7 @@ rql.keys # or rql.keys(scan_size: 123)
1298
1300
 
1299
1301
  - get list of locks with their info;
1300
1302
  - uses redis `SCAN` under the hod;
1301
- - accepts `scan_size:`/`Integer` option (`config[:key_extraction_batch_size]` by default);
1303
+ - accepts `scan_size:`/`Integer` option (`config['key_extraction_batch_size']` by default);
1302
1304
  - returns `Set<Hash<Symbol,Any>>` (see [#lock_info](#lock_info) and examples below for details).
1303
1305
  - contained data: `{ lock: String, status: Symbol, info: Hash<String,Any> }`;
1304
1306
  - `:lock` - `String` - lock key in Redis;
@@ -1336,11 +1338,11 @@ rql.locks_info # or rql.locks_info(scan_size: 123)
1336
1338
 
1337
1339
  - get list of queues with their info;
1338
1340
  - uses redis `SCAN` under the hod;
1339
- - accepts `scan_size:`/`Integer` option (`config[:key_extraction_batch_size]` by default);
1341
+ - accepts `scan_size:`/`Integer` option (`config['key_extraction_batch_size']` by default);
1340
1342
  - returns `Set<Hash<Symbol,Any>>` (see [#queue_info](#queue_info) and examples below for details).
1341
1343
  - contained data: `{ queue: String, requests: Array<Hash<String,Any>> }`
1342
1344
  - `:queue` - `String` - lock key queue in Redis;
1343
- - `:requests` - `Array<Hash<String,Any>>` - lock requests in the que with their acquier id and score.
1345
+ - `:requests` - `Array<Hash<String,Any>>` - lock requests in the que with their acquirer id and score.
1344
1346
 
1345
1347
  ```ruby
1346
1348
  rql.queues_info # or rql.qeuues_info(scan_size: 123)
@@ -1371,7 +1373,7 @@ For this case your lock reuquest will be cleared only when any process will try
1371
1373
  to acquire this lock again (cuz lock acquirement triggers the removement of expired requests).
1372
1374
 
1373
1375
  In order to help with these dead requests you may periodically call `#clear_dead_requests`
1374
- with corresponding `:dead_ttl` option, that is pre-configured by default via `config[:dead_request_ttl]`.
1376
+ with corresponding `:dead_ttl` option, that is pre-configured by default via `config['dead_request_ttl']`.
1375
1377
 
1376
1378
  `:dead_ttl` option is required because of it is no any **fast** and **resource-free** way to understand which request
1377
1379
  is dead now and is it really dead cuz each request queue can host their requests with
@@ -1380,41 +1382,41 @@ a custom queue ttl for each request differently.
1380
1382
  Accepts:
1381
1383
  - `:dead_ttl` - (optional) `[Integer]`
1382
1384
  - lock request ttl after which a lock request is considered dead;
1383
- - has a preconfigured value in `config[:dead_request_ttl]` (1 day by default);
1385
+ - has a preconfigured value in `config['dead_request_ttl']` (1 day by default);
1384
1386
  - `:sacn_size` - (optional) `[Integer]`
1385
1387
  - the batch of scanned keys for Redis'es SCAN command;
1386
- - has a preconfigured valie in `config[:lock_release_batch_size]`;
1388
+ - has a preconfigured valie in `config['lock_release_batch_size']`;
1387
1389
  - `:logger` - (optional) `[::Logger,#debug]`
1388
1390
  - custom logger object;
1389
- - pre-configured in `config[:logger]`;
1391
+ - pre-configured in `config['logger']`;
1390
1392
  - `:instrumenter` - (optional) `[#notify]`
1391
1393
  - custom instrumenter object;
1392
- - pre-configured in `config[:isntrumenter]`;
1394
+ - pre-configured in `config['isntrumenter']`;
1393
1395
  - `:instrument` - (optional) `[NilClass,Any]`
1394
1396
  - custom instrumentation data wich will be passed to the instrumenter's payload with :instrument key;
1395
1397
  - `nil` by default (no additional data);
1396
1398
  - `:log_sampling_enabled` - (optional) `[Boolean]`
1397
1399
  - enables **log sampling**;
1398
- - pre-configured in `config[:log_sampling_enabled]`;
1400
+ - pre-configured in `config['log_sampling_enabled']`;
1399
1401
  - `:log_sampling_percent` - (optional) `[Integer]`
1400
1402
  - **log sampling**:the percent of cases that should be logged;
1401
- - pre-configured in `config[:log_sampling_percent]`;
1403
+ - pre-configured in `config['log_sampling_percent']`;
1402
1404
  - `:log_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Logging::Sampler>]`
1403
1405
  - **log sampling**: percent-based log sampler that decides should be RQL case logged or not;
1404
- - pre-configured in `config[:log_sampler]`;
1406
+ - pre-configured in `config['log_sampler']`;
1405
1407
  - `log_sample_this` - (optional) `[Boolean]`
1406
1408
  - marks the method that everything should be logged despite the enabled log sampling;
1407
1409
  - makes sense when log sampling is enabled;
1408
1410
  - `false` by default;
1409
1411
  - `:instr_sampling_enabled` - (optional) `[Boolean]`
1410
1412
  - enables **instrumentaion sampling**;
1411
- - pre-configured in `config[:instr_sampling_enabled]`;
1413
+ - pre-configured in `config['instr_sampling_enabled']`;
1412
1414
  - `instr_sampling_percent` - (optional) `[Integer]`
1413
1415
  - the percent of cases that should be instrumented;
1414
- - pre-configured in `config[:instr_sampling_percent]`;
1416
+ - pre-configured in `config['instr_sampling_percent']`;
1415
1417
  - `instr_sampler` - (optional) `[#sampling_happened?,Module<RedisQueuedLocks::Instrument::Sampler>]`
1416
1418
  - percent-based log sampler that decides should be RQL case instrumented or not;
1417
- - pre-configured in `config[:instr_sampler]`;
1419
+ - pre-configured in `config['instr_sampler']`;
1418
1420
  - `instr_sample_this` - (optional) `[Boolean]`
1419
1421
  - marks the method that everything should be instrumneted despite the enabled instrumentation sampling;
1420
1422
  - makes sense when instrumentation sampling is enabled;
@@ -1464,7 +1466,7 @@ Accepts:
1464
1466
  - `identity:` - (optional) `[String,Any]`;
1465
1467
  - this value is calculated once during `RedisQueuedLock::Client` instantiation and stored in `@uniq_identity`;
1466
1468
  - this value can be accessed from `RedisQueuedLock::Client#uniq_identity`;
1467
- - [Configuration](#configuration) documentation: see `config[:uniq_identifier]`;
1469
+ - [Configuration](#configuration) documentation: see `config['uniq_identifier']`;
1468
1470
  - [#lock](#lock---obtain-a-lock) method documentation: see `uniq_identifier`;
1469
1471
 
1470
1472
  ```ruby
@@ -1505,7 +1507,7 @@ Accepts:
1505
1507
  - `identity:` - (optional) `[String]`;
1506
1508
  - this value is calculated once during `RedisQueuedLock::Client` instantiation and stored in `@uniq_identity`;
1507
1509
  - this value can be accessed from `RedisQueuedLock::Client#uniq_identity`;
1508
- - [Configuration](#configuration) documentation: see `config[:uniq_identifier]`;
1510
+ - [Configuration](#configuration) documentation: see `config['uniq_identifier']`;
1509
1511
  - [#lock](#lock---obtain-a-lock) method documentation: see `uniq_identifier`;
1510
1512
 
1511
1513
  ```ruby
@@ -1537,7 +1539,7 @@ Accepts:
1537
1539
  - `identity` - (optional) `[String]`;
1538
1540
  - this value is calculated once during `RedisQueuedLock::Client` instantiation and stored in `@uniq_identity`;
1539
1541
  - this value can be accessed from `RedisQueuedLock::Client#uniq_identity`;
1540
- - [Configuration](#configuration) documentation: see `config[:uniq_identifier]`;
1542
+ - [Configuration](#configuration) documentation: see `config['uniq_identifier']`;
1541
1543
  - [#lock](#lock---obtain-a-lock) method documentation: see `uniq_identifier`;
1542
1544
 
1543
1545
  ```ruby
@@ -1576,7 +1578,7 @@ rql.possible_host_ids
1576
1578
  - [zombies_info](#zombies_info)
1577
1579
  - [zombie_locks](#zombie_locks)
1578
1580
  - [zombie_hosts](#zombie_hosts)
1579
- - [zombie_acquiers](#zombie_acquiers)
1581
+ - [zombie_acquirers](#zombie_acquirers)
1580
1582
 
1581
1583
  <hr>
1582
1584
 
@@ -1592,31 +1594,31 @@ rql.possible_host_ids
1592
1594
 
1593
1595
  clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
1594
1596
  # NOTE: auto-swarm your RQL client after initalization (run swarm elements and their supervisor)
1595
- config.swarm.auto_swarm = false
1597
+ config['swarm.auto_swarm'] = false
1596
1598
 
1597
1599
  # supervisor configs
1598
- config.swarm.supervisor.liveness_probing_period = 2 # NOTE: in seconds
1600
+ config['swarm.supervisor.liveness_probing_period'] = 2 # NOTE: in seconds
1599
1601
 
1600
1602
  # (probe_hosts) host probing configuration
1601
- config.swarm.probe_hosts.enabled_for_swarm = true # NOTE: run host-probing from or not
1602
- config.swarm.probe_hosts.probe_period = 2 # NOTE: (in seconds) the period of time when the probing process is triggered
1603
+ config['swarm.probe_hosts.enabled_for_swarm'] = true # NOTE: run host-probing from or not
1604
+ config['swarm.probe_hosts.probe_period'] = 2 # NOTE: (in seconds) the period of time when the probing process is triggered
1603
1605
  # (probe_hosts) individual redis config
1604
- config.swarm.probe_hosts.redis_config.sentinel = false # NOTE: individual redis config
1605
- config.swarm.probe_hosts.redis_config.pooled = false # NOTE: individual redis config
1606
- config.swarm.probe_hosts.redis_config.config = {} # NOTE: individual redis config
1607
- config.swarm.probe_hosts.redis_config.pool_config = {} # NOTE: individual redis config
1606
+ config['swarm.probe_hosts.redis_config.sentinel'] = false # NOTE: individual redis config
1607
+ config['swarm.probe_hosts.redis_config.pooled'] = false # NOTE: individual redis config
1608
+ config['swarm.probe_hosts.redis_config.config'] = {} # NOTE: individual redis config
1609
+ config['swarm.probe_hosts.redis_config.pool_config'] = {} # NOTE: individual redis config
1608
1610
 
1609
1611
  # (flush_zombies) zombie flushing configuration
1610
- config.swarm.flush_zombies.enabled_for_swarm = true # NOTE: run zombie flushing or not
1611
- config.swarm.flush_zombies.zombie_flush_period = 10 # NOTE: (in seconds) period of time when the zombie flusher is triggered
1612
- config.swarm.flush_zombies.zombie_ttl = 15_000 # NOTE: (in milliseconds) when the lock/host/acquier is considered a zombie
1613
- config.swarm.flush_zombies.zombie_lock_scan_size = 500 # NOTE: scan sizec during zombie flushing
1614
- config.swarm.flush_zombies.zombie_queue_scan_size = 500 # NOTE: scan sizec during zombie flushing
1612
+ config['swarm.flush_zombies.enabled_for_swarm'] = true # NOTE: run zombie flushing or not
1613
+ config['swarm.flush_zombies.zombie_flush_period'] = 10 # NOTE: (in seconds) period of time when the zombie flusher is triggered
1614
+ config['swarm.flush_zombies.zombie_ttl'] = 15_000 # NOTE: (in milliseconds) when the lock/host/acquirer is considered a zombie
1615
+ config['swarm.flush_zombies.zombie_lock_scan_size'] = 500 # NOTE: scan sizec during zombie flushing
1616
+ config['swarm.flush_zombies.zombie_queue_scan_size'] = 500 # NOTE: scan sizec during zombie flushing
1615
1617
  # (flush_zombies) individual redis config
1616
- config.swarm.flush_zombies.redis_config.sentinel = false # NOTE: individual redis config
1617
- config.swarm.flush_zombies.redis_config.pooled = false # NOTE: individual redis config
1618
- config.swarm.flush_zombies.redis_config.config = {} # NOTE: individual redis config
1619
- config.swarm.flush_zombies.redis_config.pool_config = {} # NOTE: individual redis config
1618
+ config['swarm.flush_zombies.redis_config.sentinel'] = false # NOTE: individual redis config
1619
+ config['swarm.flush_zombies.redis_config.pooled'] = false # NOTE: individual redis config
1620
+ config['swarm.flush_zombies.redis_config.config'] = {} # NOTE: individual redis config
1621
+ config['swarm.flush_zombies.redis_config.pool_config'] = {} # NOTE: individual redis config
1620
1622
  end
1621
1623
  ```
1622
1624
  </details>
@@ -1688,7 +1690,7 @@ rql.possible_host_ids
1688
1690
  :zombie_locks=>#<Set: {"rql:lock:kekpek"}>}
1689
1691
  [5] pry(main)> rql.zombie_locks
1690
1692
  => #<Set: {"rql:lock:kekpek"}>
1691
- [6] pry(main)> rql.zombie_acquiers
1693
+ [6] pry(main)> rql.zombie_acquirers
1692
1694
  => #<Set: {"rql:acq:17580/2260/2380/2280/3f16b93973612580"}>
1693
1695
  [7] pry(main)> rql.zombie_hosts
1694
1696
  => #<Set:
@@ -1730,7 +1732,7 @@ rql.possible_host_ids
1730
1732
  :flush_zombies=>{:enabled=>true, :ractor=>{:running=>true, :state=>"running"}, :main_loop=>{:running=>true, :state=>"sleep"}}}
1731
1733
  [11] pry(main)> rql.zombies_info
1732
1734
  => {:zombie_hosts=>#<Set: {}>, :zombie_acquirers=>#<Set: {}>, :zombie_locks=>#<Set: {}>}
1733
- [12] pry(main)> rql.zombie_acquiers
1735
+ [12] pry(main)> rql.zombie_acquirers
1734
1736
  => #<Set: {}>
1735
1737
  [13] pry(main)> rql.zombie_hosts
1736
1738
  => #<Set: {}>
@@ -1761,7 +1763,7 @@ rql.possible_host_ids
1761
1763
  - `:queued` (FIFO): the classic queued behavior (default), your lock will be obitaned if you are first in queue and the required lock is free;
1762
1764
  - `:random` (RANDOM): obtain a lock without checking the positions in the queue (but with checking the limist, retries, timeouts and so on). if lock is free to obtain - it will be obtained;
1763
1765
  - for current implementation detalis check:
1764
- - [Configuration](#configuration) documentation: see `config.default_access_strategy` config docs;
1766
+ - [Configuration](#configuration) documentation: see `config['default_access_strategy']` config docs;
1765
1767
  - [#lock](#lock---obtain-a-lock) method documentation: see `access_strategy` attribute docs;
1766
1768
 
1767
1769
  ---
@@ -1779,7 +1781,7 @@ rql.possible_host_ids
1779
1781
  "is your lock are obtained or not" is made as you work with **reentrant locks** (your process continues to use the lock without/with
1780
1782
  lock's TTL extension accordingly);
1781
1783
  - for current implementation details check:
1782
- - [Configuration](#configuration) documentation: see `config.default_conflict_strategy` config docs;
1784
+ - [Configuration](#configuration) documentation: see `config['default_conflict_strategy']` config docs;
1783
1785
  - [#lock](#lock---obtain-a-lock) method documentation: see `conflict_strategy` attribute docs and the method result data;
1784
1786
 
1785
1787
  ---
@@ -1796,7 +1798,7 @@ rql.possible_host_ids
1796
1798
  ```ruby
1797
1799
  "[redis_queued_locks.start_lock_obtaining]" # (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1798
1800
  "[redis_queued_locks.start_try_to_lock_cycle]" # (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1799
- "[redis_queued_locks.dead_score_reached__reset_acquier_position]" # (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1801
+ "[redis_queued_locks.dead_score_reached__reset_acquirer_position]" # (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1800
1802
  "[redis_queued_locks.lock_obtained]" # (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acq_time");
1801
1803
  "[redis_queued_locks.extendable_reentrant_lock_obtained]" # (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat", "acq_time");
1802
1804
  "[redis_queued_locks.reentrant_lock_obtained]" # (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat", "acq_time");
@@ -1831,8 +1833,8 @@ rql.possible_host_ids
1831
1833
  <sup>\[[back to top](#table-of-contents)\]</sup>
1832
1834
 
1833
1835
  **NOTICE**: logging can be sampled via:
1834
- - `config.log_samplign_enabled = true` (**false** by default);
1835
- - `config.log_sampler = RedisQueuedLocks::Logging::Sampler` (used by default);
1836
+ - `config['log_samplign_enabled'] = true` (**false** by default);
1837
+ - `config['log_sampler'] = RedisQueuedLocks::Logging::Sampler` (used by default);
1836
1838
  - see **RedisQueuedLocks::Logging::Sampler** implementation in source code for customization details;
1837
1839
 
1838
1840
  ```ruby
@@ -1843,7 +1845,7 @@ rql.possible_host_ids
1843
1845
  # - at this moment the only debug logs are realised in following cases:
1844
1846
  # - "[redis_queued_locks.start_lock_obtaining]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1845
1847
  # - "[redis_queued_locks.start_try_to_lock_cycle]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1846
- # - "[redis_queued_locks.dead_score_reached__reset_acquier_position]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1848
+ # - "[redis_queued_locks.dead_score_reached__reset_acquirer_position]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1847
1849
  # - "[redis_queued_locks.lock_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acq_time", "acs_strat");
1848
1850
  # - "[redis_queued_locks.extendable_reentrant_lock_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acq_time", "acs_strat");
1849
1851
  # - "[redis_queued_locks.reentrant_lock_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acq_time", "acs_strat");
@@ -1851,7 +1853,7 @@ rql.possible_host_ids
1851
1853
  # - "[redis_queued_locks.expire_lock]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1852
1854
  # - "[redis_queued_locks.decrease_lock]" (logs "lock_key", "decreased_ttl", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1853
1855
  # - by default uses VoidLogger that does nothing;
1854
- config.logger = RedisQueuedLocks::Logging::VoidLogger
1856
+ config['logger'] = RedisQueuedLocks::Logging::VoidLogger
1855
1857
 
1856
1858
  # (default: false)
1857
1859
  # - adds additional debug logs;
@@ -1870,28 +1872,28 @@ config.logger = RedisQueuedLocks::Logging::VoidLogger
1870
1872
  # - "[redis_queued_locks.try_lock.exit__no_first]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat", "first_acq_id_in_queue", "<current_lock_data>");
1871
1873
  # - "[redis_queued_locks.try_lock.exit__lock_still_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat", "first_acq_id_in_queue", "locked_by_acq_id", "<current_lock_data>");
1872
1874
  # - "[redis_queued_locks.try_lock.obtain__free_to_acquire]" (logs "lock_key", "queue_ttl", "acq_id", "hst_id", "acs_strat");
1873
- config.log_lock_try = false
1875
+ config['log_lock_try'] = false
1874
1876
 
1875
1877
  # (default: false)
1876
1878
  # - enables <log sampling>: only the configured percent of RQL cases will be logged;
1877
1879
  # - disabled by default;
1878
- # - works in tandem with <config.log_sampling_percent> and <log.sampler> configs;
1879
- config.log_sampling_enabled = false
1880
+ # - works in tandem with <config['log_sampling_percent']> and <config['log_sampler']> configs;
1881
+ config['log_sampling_enabled'] = false
1880
1882
 
1881
1883
  # (default: 15)
1882
1884
  # - the percent of cases that should be logged;
1883
- # - take an effect when <config.log_sampling_enalbed> is true;
1884
- # - works in tandem with <config.log_sampling_enabled> and <config.log_sampler> configs;
1885
- config.log_sampling_percent = 15
1885
+ # - take an effect when <config['log_sampling_enalbed']> is true;
1886
+ # - works in tandem with <config['log_sampling_enabled']> and <config['log_sampler']> configs;
1887
+ config['log_sampling_percent'] = 15
1886
1888
 
1887
1889
  # (default: RedisQueuedLocks::Logging::Sampler)
1888
1890
  # - percent-based log sampler that decides should be RQL case logged or not;
1889
- # - works in tandem with <config.log_sampling_enabled> and <config.log_sampling_percent> configs;
1891
+ # - works in tandem with <config['log_sampling_enabled']> and <config['log_sampling_percent']> configs;
1890
1892
  # - based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
1891
1893
  # method so the algorithm error is ~(0%..13%);
1892
1894
  # - you can provide your own log sampler with bettter algorithm that should realize
1893
1895
  # `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Logging::Sampler` for example);
1894
- config.log_sampler = RedisQueuedLocks::Logging::Sampler
1896
+ config['log_sampler'] = RedisQueuedLocks::Logging::Sampler
1895
1897
  ```
1896
1898
 
1897
1899
  ---
@@ -1903,7 +1905,7 @@ config.log_sampler = RedisQueuedLocks::Logging::Sampler
1903
1905
  - [Instrumentation Events](#instrumentation-events)
1904
1906
  - [Instrumentation Configuration](#instrumentation-configuration)
1905
1907
 
1906
- An instrumentation layer is incapsulated in `instrumenter` object stored in [config](#configuration) (`RedisQueuedLocks::Client#config[:instrumenter]`).
1908
+ An instrumentation layer is incapsulated in `instrumenter` object stored in [config](#configuration) (`RedisQueuedLocks::Client#config['instrumenter']`).
1907
1909
 
1908
1910
  Instrumentation can be sampled. See [Instrumentation Configuration](#instrumentation-configuration) section for details.
1909
1911
 
@@ -1927,8 +1929,8 @@ By default `RedisQueuedLocks::Client` is configured with the void notifier (whic
1927
1929
  <sup>\[[back to top](#table-of-contents)\]</sup>
1928
1930
 
1929
1931
  **NOTICE**: instrumentation can be sampled via:
1930
- - `config.instr_sampling_enabled = true` (**false** by default);
1931
- - `config.instr_sampler = RedisQueuedLocks::Instrument::Sampler` (used by default);
1932
+ - `config['instr_sampling_enabled'] = true` (**false** by default);
1933
+ - `config['instr_sampler'] = RedisQueuedLocks::Instrument::Sampler` (used by default);
1932
1934
  - see **RedisQueuedLocks::Instrument::Sampler** implementation in source code for customization details;
1933
1935
 
1934
1936
  ```ruby
@@ -1938,28 +1940,28 @@ By default `RedisQueuedLocks::Client` is configured with the void notifier (whic
1938
1940
  # - event: <string> requried;
1939
1941
  # - payload: <hash> requried;
1940
1942
  # - disabled by default via `VoidNotifier`;
1941
- config.instrumenter = RedisQueuedLocks::Instrument::ActiveSupport
1943
+ config['instrumenter'] = RedisQueuedLocks::Instrument::ActiveSupport
1942
1944
 
1943
1945
  # (default: false)
1944
1946
  # - enables <instrumentaion sampling>: only the configured percent of RQL cases will be instrumented;
1945
1947
  # - disabled by default;
1946
- # - works in tandem with <config.instr_sampling_percent and <log.instr_sampler>;
1947
- config.instr_sampling_enabled = false
1948
+ # - works in tandem with <config['instr_sampling_percent']> and <config['instr_sampler']>;
1949
+ config['instr_sampling_enabled'] = false
1948
1950
 
1949
1951
  # (default: 15)
1950
1952
  # - the percent of cases that should be instrumented;
1951
- # - take an effect when <config.instr_sampling_enalbed> is true;
1952
- # - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampler> configs;
1953
- config.instr_sampling_percent = 15
1953
+ # - take an effect when <config['instr_sampling_enalbed']> is true;
1954
+ # - works in tandem with <config['instr_sampling_enabled']> and <config['instr_sampler']> configs;
1955
+ config['instr_sampling_percent'] = 15
1954
1956
 
1955
1957
  # (default: RedisQueuedLocks::Instrument::Sampler)
1956
1958
  # - percent-based log sampler that decides should be RQL case instrumented or not;
1957
- # - works in tandem with <config.instr_sampling_enabled> and <config.instr_sampling_percent> configs;
1959
+ # - works in tandem with <config['instr_sampling_enabled']> and <config['instr_sampling_percent']> configs;
1958
1960
  # - based on the ultra simple percent-based (weight-based) algorithm that uses SecureRandom.rand
1959
1961
  # method so the algorithm error is ~(0%..13%);
1960
1962
  # - you can provide your own log sampler with bettter algorithm that should realize
1961
1963
  # `sampling_happened?(percent) => boolean` interface (see `RedisQueuedLocks::Instrument::Sampler` for example);
1962
- config.instr_sampler = RedisQueuedLocks::Instrument::Sampler
1964
+ config['instr_sampler'] = RedisQueuedLocks::Instrument::Sampler
1963
1965
  ```
1964
1966
 
1965
1967
  ---
@@ -1985,7 +1987,7 @@ Detalized event semantics and payload structure:
1985
1987
  - raised from `#lock`/`#lock!`;
1986
1988
  - payload:
1987
1989
  - `:ttl` - `integer`/`milliseconds` - lock ttl;
1988
- - `:acq_id` - `string` - lock acquier identifier;
1990
+ - `:acq_id` - `string` - lock acquirer identifier;
1989
1991
  - `:hst_id` - `string` - lock's host identifier;
1990
1992
  - `:lock_key` - `string` - lock name;
1991
1993
  - `:ts` - `numeric`/`epoch` - the time when the lock was obtaiend;
@@ -1998,7 +2000,7 @@ Detalized event semantics and payload structure:
1998
2000
  - payload:
1999
2001
  - `:lock_key` - `string` - lock name;
2000
2002
  - `:ttl` - `integer`/`milliseconds` - last lock ttl by reentrant locking;
2001
- - `:acq_id` - `string` - lock acquier identifier;
2003
+ - `:acq_id` - `string` - lock acquirer identifier;
2002
2004
  - `:hst_id` - `string` - lock's host identifier;
2003
2005
  - `:ts` - `numeric`/`epoch` - the time when the lock was obtaiend as extendable reentrant lock;
2004
2006
  - `:acq_time` - `float`/`milliseconds` - time spent on lock acquiring;
@@ -2010,7 +2012,7 @@ Detalized event semantics and payload structure:
2010
2012
  - payload:
2011
2013
  - `:lock_key` - `string` - lock name;
2012
2014
  - `:ttl` - `integer`/`milliseconds` - last lock ttl by reentrant locking;
2013
- - `:acq_id` - `string` - lock acquier identifier;
2015
+ - `:acq_id` - `string` - lock acquirer identifier;
2014
2016
  - `:hst_id` - `string` - lock's host identifier;
2015
2017
  - `:ts` - `numeric`/`epoch` - the time when the lock was obtaiend as reentrant lock;
2016
2018
  - `:acq_time` - `float`/`milliseconds` - time spent on lock acquiring;
@@ -2022,7 +2024,7 @@ Detalized event semantics and payload structure:
2022
2024
  - payload:
2023
2025
  - `:hold_time` - `float`/`milliseconds` - lock hold time;
2024
2026
  - `:ttl` - `integer`/`milliseconds` - lock ttl;
2025
- - `:acq_id` - `string` - lock acquier identifier;
2027
+ - `:acq_id` - `string` - lock acquirer identifier;
2026
2028
  - `:hst_id` - `string` - lock's host identifier;
2027
2029
  - `:lock_key` - `string` - lock name;
2028
2030
  - `:ts` - `numeric`/`epoch` - the time when lock was obtained;
@@ -2036,7 +2038,7 @@ Detalized event semantics and payload structure:
2036
2038
  - payload:
2037
2039
  - `:hold_time` - `float`/`milliseconds` - lock hold time;
2038
2040
  - `:ttl` - `integer`/`milliseconds` - last lock ttl by reentrant locking;
2039
- - `:acq_id` - `string` - lock acquier identifier;
2041
+ - `:acq_id` - `string` - lock acquirer identifier;
2040
2042
  - `:hst_id` - `string` - lock's host identifier;
2041
2043
  - `:ts` - `numeric`/`epoch` - the time when the lock was obtaiend as reentrant lock;
2042
2044
  - `:lock_key` - `string` - lock name;
@@ -2073,26 +2075,52 @@ Detalized event semantics and payload structure:
2073
2075
  trying to ressurect unexpectedly terminated swarm elements, and will notify about this;
2074
2076
  - swarm logs (thread/ractor has some limitations so the initial implementation does not include swarm logging);
2075
2077
  - swarm instrumentation (thread/ractor has some limitations so the initial implementation does not include swarm instrumentation);
2078
+ - isolated timeouts which are independent of internal Ruby's timeout implementation (where all timeouts are hostend inside
2079
+ the global "timeout request" queue and managed by a single global "timeout wathcer" thread). it should prevent any logic and timeout intersections,
2080
+ some GVL-related things and problem situations when the global watcher thread is "dead";
2076
2081
  - lock request prioritization;
2077
- - **strict redlock algorithm support** (support for many `RedisClient` instances);
2082
+ - **strict redlock algorithm support** (support for many `RedisClient` instances that are fully independent (distributed redis instances));
2078
2083
  - `#lock_series` - acquire a series of locks:
2079
2084
  ```ruby
2080
2085
  rql.lock_series('lock_a', 'lock_b', 'lock_c') { puts 'locked' }
2081
2086
  ```
2082
- - support for `Dragonfly` database backend (https://github.com/dragonflydb/dragonfly) (https://www.dragonflydb.io/);
2087
+ - an ability to release all locks and all requests of the concrete acquirer id or host id (or both in validation-orianted combination);
2088
+ - detailed lock informotion inside the error object in cases of exceptions (at the moment we have this info inside the error message only that hard to analyze in work);
2089
+ - a convenient way to mark any `lock` invocation as "non-instrumentable" / "non-loggable" (as an alternative to `VoidNotifier` and to `VoidLogger`);
2090
+ - `Read`/`Write` semantics: you can mark your locks as `read` or `write` lock in order to simulate `read`/`write` lock behavior:
2091
+ - `read` - watis - `write`;
2092
+ - `read` - not waits - `read`;
2093
+ - `write` - waits - `read`;
2094
+ - `write` - waits - `write`;
2095
+ - **write** mode is a default behavior for all RQL locks;
2083
2096
  - **Minor**:
2097
+ - `#lock`/`#lock!` - `timeout:` option: support for granular periods (it supports only `seconds` at the moment, but we need `milliseconds`);
2098
+ - Add `after timeout hook` ability for timeout errors with an ability to access the binding context (if it possibly) of the thread where it failed;
2099
+ - Add `ignore timeout errors` ability (for debug purposes);
2100
+ - A special explicit documentation section that will explain and clarify which exceptions can be occured and what cases occurs them (at the moment such cases are explained inside the lock methods documentation that is not really convinient);
2101
+ - Renaming of some exceptions (such as `RedisQueuedLocks::TimedLockTimeoutError`) to make the related problem more quickly, faster and easier to understand;
2102
+ - Support for detailed `OpenTelemetry` tracing;
2103
+ - `light mode`: an ability to work without any debug and instrumentation logic and data (totally reduced debugging and instrumenting possibilities, but better performance);
2104
+ - support for `Dragonfly` database backend (https://github.com/dragonflydb/dragonfly) (https://www.dragonflydb.io/);
2105
+ - (_research_) GVL-isolation for lock acquirement logic (try to bypass Ruby's "context-switching" in order to prevent any time-based affects on lock-acquirement logic);
2084
2106
  - Semantic error objects for unexpected Redis errors;
2085
2107
  - **Experimental feature**: (non-`timed` locks): per-ruby-block-holding-the-lock sidecar `Ractor` and `in progress queue` in RedisDB that will extend
2086
2108
  the acquired lock for long-running blocks of code (that invoked "under" the lock
2087
2109
  whose ttl may expire before the block execution completes). It makes sense for non-`timed` locks *only*;
2110
+ - sized lock queues (with an ability of dynamically growing size);
2088
2111
  - better code stylization (+ some refactorings);
2089
- - `RedisQueuedLocks::Acquier::Try.try_to_lock` - detailed successful result analization;
2112
+ - `RedisQueuedLocks::Acquirer::Try.try_to_lock` - detailed successful result analization;
2090
2113
  - Support for LIFO strategy;
2091
2114
  - better specs with 100% test coverage (total specs rework);
2092
2115
  - statistics with UI;
2093
2116
  - JSON log formatter;
2117
+ - **automatic** deadlock detection;
2094
2118
  - `go`-lang implementation;
2095
-
2119
+ - (_research_) simplification and speedup of the internal "redis-communuication-and-data-storing"-based algorithms;
2120
+ - `unlock_on:`-option in lock/lock! logic in order to support auto-unlocking on any exception rasaied under the invoked block (invoked under the lock);
2121
+ - **Research**: support for `Valkey` database backend (https://github.com/valkey-io/valkey) (https://valkey.io/);
2122
+ - **Research**: support for `Garnet` database backend (https://microsoft.github.io/) (https://github.com/microsoft/garnet);
2123
+ - add a library-level exception, when RQL-related key (required for it's logic) has incompatible type (means: some other program uses our key with their own type and logic and RQL can't work properly);
2096
2124
  ---
2097
2125
 
2098
2126
  ## Contributing