redis_queued_locks 0.0.40 → 1.1.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.
- 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 ·  
|
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.
|