redis_queued_locks 0.0.40 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +43 -18
- data/lib/redis_queued_locks/acquier/acquire_lock.rb +1 -1
- data/lib/redis_queued_locks/client.rb +6 -5
- data/lib/redis_queued_locks/version.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6b175564df436902d56e07a376f0257118eced8d7c81dbb81837e63cdef74938
|
4
|
+
data.tar.gz: f88d3e83045cb4dd4dcd10b12744399ce45d3b99a84f6ca492d801a678db55f0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae486564a408bc9039d6b09f3fe08ba37e733bae902ec2c3f55eae84b22a05e6c6f31bc9ceafc5ee78a10ae34dfdc0b3e7dcbfb09a41f74795ed29dce823a6bc
|
7
|
+
data.tar.gz: ba40ab572fb1863b0bcddee6536385d19e3b3c7c9df07b2e2d71d74ad740eccb05a18847222be70bf6796596ce2b93266dbf462dccab294c6200a4441ca1f1a7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,18 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [1.1.0] - 2024-04-01
|
4
|
+
### Added
|
5
|
+
- Documentation updates:
|
6
|
+
- more `#lock` examples;
|
7
|
+
- added missing docs for `config.dead_request_ttl`;
|
8
|
+
- some minor updates;
|
9
|
+
### Changed
|
10
|
+
- `#clear_dead_requests`: `:scan_size` is equal to `config[:lock_release_batch_size]` now (instead of to `config[:key_extraction_batch_size]`);
|
11
|
+
cuz `#clear_dead_requests` works with lock releasing;
|
12
|
+
|
13
|
+
## [1.0.0] - 2024-04-01
|
14
|
+
- First Major Release;
|
15
|
+
|
3
16
|
## [0.0.40] - 2024-04-01
|
4
17
|
### Added
|
5
18
|
- `RedisQueuedLocks::Client#clear_dead_requests` implementation;
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# RedisQueuedLocks ·
|
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)
|
2
2
|
|
3
3
|
<a href="https://redis.io/docs/manual/patterns/distributed-locks/">Distributed locks</a> with "lock acquisition queue" capabilities based on the Redis Database.
|
4
4
|
|
@@ -155,10 +155,16 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
|
|
155
155
|
config.lock_release_batch_size = 100
|
156
156
|
|
157
157
|
# (default: 500)
|
158
|
-
# - how many items should be extracted from redis during the #locks, #queues
|
158
|
+
# - how many items should be extracted from redis during the #locks, #queues, #keys
|
159
|
+
# #locks_info, and #queues_info operations (uses SCAN);
|
159
160
|
# - affects the performance of your Redis and Ruby Application (configure thoughtfully;)
|
160
161
|
config.key_extraction_batch_size = 500
|
161
162
|
|
163
|
+
# (default: 1 day)
|
164
|
+
# - the default period of time (in milliseconds) after which a lock request is considered dead;
|
165
|
+
# - used for `#clear_dead_requests` as default vaule of `:dead_ttl` option;
|
166
|
+
config.dead_request_ttl = (1 * 24 * 60 * 60 * 1000) # one day in milliseconds
|
167
|
+
|
162
168
|
# (default: RedisQueuedLocks::Instrument::VoidNotifier)
|
163
169
|
# - instrumentation layer;
|
164
170
|
# - you can provde your own instrumenter with `#notify(event, payload = {})`
|
@@ -245,7 +251,7 @@ def lock(
|
|
245
251
|
ttl: config[:default_lock_ttl],
|
246
252
|
queue_ttl: config[:default_queue_ttl],
|
247
253
|
timeout: config[:try_to_lock_timeout],
|
248
|
-
timed:
|
254
|
+
timed: config[:is_timed_by_default],
|
249
255
|
retry_count: config[:retry_count],
|
250
256
|
retry_delay: config[:retry_delay],
|
251
257
|
retry_jitter: config[:retry_jitter],
|
@@ -429,6 +435,24 @@ rql.lock("my_lock", ttl: 6_500) # blocks execution until the lock is obtained
|
|
429
435
|
puts "Let's go" # will be called immediately after the lock is obtained
|
430
436
|
```
|
431
437
|
|
438
|
+
- add custom metadata to the lock (via `:meta` option):
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
rql.lock("my_lock", ttl: 123456, meta: { "some" => "data", key: 123.456 })
|
442
|
+
|
443
|
+
rql.lock_info("my_lock")
|
444
|
+
# =>
|
445
|
+
{
|
446
|
+
"lock_key" => "rql:lock:my_lock",
|
447
|
+
"acq_id" => "rql:acq:123/456/567/678/374dd74324",
|
448
|
+
"ts" => 123456789,
|
449
|
+
"ini_ttl" => 123456,
|
450
|
+
"rem_ttl" => 123440,
|
451
|
+
"some" => "data",
|
452
|
+
"key" => "123.456" # NOTE: returned as a raw string directly from Redis
|
453
|
+
}
|
454
|
+
```
|
455
|
+
|
432
456
|
---
|
433
457
|
|
434
458
|
#### #lock! - exceptional lock obtaining
|
@@ -632,12 +656,12 @@ rql.unlock("your_lock_name")
|
|
632
656
|
- pre-configured in `config[:lock_release_batch_size]`;
|
633
657
|
- `:logger` - (optional) `[::Logger,#debug]`
|
634
658
|
- custom logger object;
|
635
|
-
-
|
659
|
+
- pre-configured value in `config[:logger]`;
|
636
660
|
- `:instrumenter` - (optional) `[#notify]`
|
637
661
|
- custom instrumenter object;
|
638
|
-
-
|
662
|
+
- pre-configured value in `config[:isntrumenter]`;
|
639
663
|
- `:instrument` - (optional) `[NilClass,Any]`
|
640
|
-
- custom instrumentation data wich will be passed to the instrumenter's payload with
|
664
|
+
- custom instrumentation data wich will be passed to the instrumenter's payload with `:instrument` key;
|
641
665
|
|
642
666
|
- returns:
|
643
667
|
- `[Hash<Symbol,Numeric>]` - Format: `{ ok: true, result: Hash<Symbol,Numeric> }`;
|
@@ -865,15 +889,16 @@ rql.queues_info # or rql.qeuues_info(scan_size: 123)
|
|
865
889
|
|
866
890
|
<sup>\[[back to top](#usage)\]</sup>
|
867
891
|
|
868
|
-
In some cases your lock requests may become "dead". It
|
869
|
-
that are enqueeud to the lock queue is failed unexpectedly (for some reason)
|
870
|
-
and when no any other process does not need this lock anymore.
|
871
|
-
|
892
|
+
In some cases your lock requests may become "dead". It means that your lock request lives in lock queue in Redis without
|
893
|
+
any processing. It can happen when your processs that are enqueeud to the lock queue is failed unexpectedly (for some reason)
|
894
|
+
before the lock acquire moment occurs and when no any other process does not need this lock anymore.
|
895
|
+
For this case your lock reuquest will be cleared only when any process will try
|
896
|
+
to acquire this lock again (cuz lock acquirement triggers the removement of expired requests).
|
872
897
|
|
873
898
|
In order to help with these dead requests you may periodically call `#clear_dead_requests`
|
874
|
-
with corresponding
|
899
|
+
with corresponding `:dead_ttl` option, that is pre-configured by default via `config[:dead_request_ttl]`.
|
875
900
|
|
876
|
-
|
901
|
+
`:dead_ttl` option is required because of it is no any **fast** and **resource-free** way to understand which request
|
877
902
|
is dead now and is it really dead cuz each request queue can host their requests with
|
878
903
|
a custom queue ttl for each request differently.
|
879
904
|
|
@@ -1026,15 +1051,15 @@ Detalized event semantics and payload structure:
|
|
1026
1051
|
|
1027
1052
|
<sup>\[[back to top](#table-of-contents)\]</sup>
|
1028
1053
|
|
1054
|
+
- **strict redlock algorithm support** (support for many `RedisClient` instances);
|
1029
1055
|
- Semantic Error objects for unexpected Redis errors;
|
1030
|
-
- better specs with 100% test coverage;
|
1031
|
-
- per-block-holding-the-lock sidecar `Ractor` and `in progress queue` in RedisDB that will extend
|
1056
|
+
- better specs with 100% test coverage (total rework);
|
1057
|
+
- (non-`timed` locks): per-ruby-block-holding-the-lock sidecar `Ractor` and `in progress queue` in RedisDB that will extend
|
1032
1058
|
the acquired lock for long-running blocks of code (that invoked "under" the lock
|
1033
|
-
whose ttl may expire before the block execution completes). It
|
1034
|
-
- lock prioritization;
|
1059
|
+
whose ttl may expire before the block execution completes). It makes sense for non-`timed` locks *only*;
|
1060
|
+
- lock request prioritization;
|
1035
1061
|
- support for LIFO strategy;
|
1036
|
-
- structured logging (separated docs);
|
1037
|
-
- GitHub Actions CI;
|
1062
|
+
- more structured logging (separated docs);
|
1038
1063
|
- `RedisQueuedLocks::Acquier::Try.try_to_lock` - detailed successful result analization;
|
1039
1064
|
- better code stylization (+ some refactorings);
|
1040
1065
|
- statistics with UI;
|
@@ -186,7 +186,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
186
186
|
with_acq_timeout(timeout, lock_key, raise_errors, on_timeout: acq_dequeue) do
|
187
187
|
acq_start_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
188
188
|
|
189
|
-
# Step 2.1:
|
189
|
+
# Step 2.1: cyclically try to obtain the lock
|
190
190
|
while acq_process[:should_try]
|
191
191
|
run_non_critical do
|
192
192
|
logger.debug do
|
@@ -402,11 +402,12 @@ class RedisQueuedLocks::Client
|
|
402
402
|
end
|
403
403
|
|
404
404
|
# @option dead_ttl [Integer]
|
405
|
-
#
|
406
|
-
#
|
407
|
-
#
|
405
|
+
# - the time period (in millsiecnds) after whcih the lock request is
|
406
|
+
# considered as dead;
|
407
|
+
# - `config[:dead_request_ttl]` is used by default;
|
408
408
|
# @option scan_size [Integer]
|
409
|
-
#
|
409
|
+
# - the batch of scanned keys for Redis'es SCAN command;
|
410
|
+
# - `config[:lock_release_batch_size]` is used by default;
|
410
411
|
# @option logger [::Logger,#debug]
|
411
412
|
# @option instrumenter [#notify]
|
412
413
|
# @option instrument [NilClass,Any]
|
@@ -417,7 +418,7 @@ class RedisQueuedLocks::Client
|
|
417
418
|
# @since 0.1.0
|
418
419
|
def clear_dead_requests(
|
419
420
|
dead_ttl: config[:dead_request_ttl],
|
420
|
-
scan_size: config[:
|
421
|
+
scan_size: config[:lock_release_batch_size],
|
421
422
|
logger: config[:logger],
|
422
423
|
instrumenter: config[:instrumenter],
|
423
424
|
instrument: nil
|
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:
|
4
|
+
version: 1.1.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-
|
11
|
+
date: 2024-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis-client
|
@@ -108,7 +108,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
110
|
requirements: []
|
111
|
-
rubygems_version: 3.
|
111
|
+
rubygems_version: 3.5.1
|
112
112
|
signing_key:
|
113
113
|
specification_version: 4
|
114
114
|
summary: Queued distributed locks based on Redis.
|