redis_queued_locks 1.16.0 → 1.16.1
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 +26 -1
- data/README.md +59 -13
- data/lib/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rb +1 -24
- data/lib/redis_queued_locks/acquirer/acquire_lock/log_visitor.rb +1 -51
- data/lib/redis_queued_locks/acquirer/acquire_lock/yield_expire/log_visitor.rb +0 -24
- data/lib/redis_queued_locks/acquirer/lock_series_poc/instr_visitor.rb +51 -0
- data/lib/redis_queued_locks/acquirer/lock_series_poc/log_visitor.rb +83 -0
- data/lib/redis_queued_locks/acquirer/lock_series_poc.rb +23 -9
- data/lib/redis_queued_locks/utilities.rb +1 -1
- data/lib/redis_queued_locks/version.rb +2 -2
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0bd0b3bb446d6ce5af47949de25834b0c4f87a3fcb1090bf9604fba129354468
|
|
4
|
+
data.tar.gz: b9c8c49560e193db92d63fc232c31fbdf1ea03b72b28fc778c3fcc22da3af1d1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dcea0a7ee67e7a727fe0d92d88bf8f6b0a946c279fce3d43f34e6fe05844cf156e9679d91fcd12f450ebd9029a0aabd9f61b9c5224b7a88fa4551202bd716939
|
|
7
|
+
data.tar.gz: 0c0b132e65106ce28f68a41278adc7981150b3a50d73952f55bfa22d0b735e8713924a20adca4caedd0fb744587a5675cbab0a78339c02d695b516129a2bd480
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,29 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [Unreleased]
|
|
2
|
+
|
|
3
|
+
## [1.16.1] - 2026-01-28
|
|
4
|
+
### Changed
|
|
5
|
+
- `lock_series` PoC:
|
|
6
|
+
- added own instrumentation visitor and log ivsitor (`RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor` and
|
|
7
|
+
`RedisQueuedLocks::Acquirer::LockSeriesPoC::InstrVisitor` respectively) and all `lock_series`-related
|
|
8
|
+
instrumentation/log methods were moved to these modules;
|
|
9
|
+
- documentaiton updates;
|
|
10
|
+
- YARDOC documentaiton updates;
|
|
11
|
+
### Added
|
|
12
|
+
- `lock_series` PoC updates:
|
|
13
|
+
- added missing instrumentation event `lock_series_obtained`;
|
|
14
|
+
- added more data to the `detailed_event: true` lock invocation result:
|
|
15
|
+
- `locks_release_strategy` - `:immediate_release_after_yield` or `:redis_key_ttl`
|
|
16
|
+
### Fixed
|
|
17
|
+
- `lock_series` PoC:
|
|
18
|
+
- incorrect instrumentation/logs data:
|
|
19
|
+
- `expire_lock_series` log and instrumentation event should not be produced
|
|
20
|
+
when locks were obtained without a block of code (for this case obtained locks
|
|
21
|
+
lives in redis with their TTL);
|
|
22
|
+
- `locks_released_at` and `locks_hold_time` of the detailed invocation result (`detailed: true`)
|
|
23
|
+
has nil values in case when locks are obtained without a block of code
|
|
24
|
+
(lokcs are not released at this moment and lives in redis with their TTL);
|
|
25
|
+
|
|
26
|
+
## [1.16.0] - 2026-01-27
|
|
2
27
|
### Added
|
|
3
28
|
- Brand new Feature **"Lock series of locks"**
|
|
4
29
|
- (*Proof of Concpet*-based implementation at the moment)
|
data/README.md
CHANGED
|
@@ -859,51 +859,97 @@ See `#lock` method [documentation](#lock---obtain-a-lock).
|
|
|
859
859
|
`lock_series` - acquire a series of locks simultaniously and hold them all while your block of code is executing
|
|
860
860
|
or (if block is not passed) while all locks will not expire.
|
|
861
861
|
|
|
862
|
+
If it is not possible to obtain all locks at the same time (taking into queue ttl, retry attempts count for each lock, etc)
|
|
863
|
+
- no any lock will be acquired.
|
|
864
|
+
|
|
865
|
+
Method options is the same as for `lock` method: `retry_count`, `retry_jitter`, `ttl`, `queue_ttl`, etc. Each option will be
|
|
866
|
+
applied with the same value to the each lock acquirement process (for each lock in a series separately).
|
|
867
|
+
|
|
862
868
|
**IMPORTANT DETAILS AND LIMITATIONS**:
|
|
863
|
-
- (this behavior will be reworked with another algorithm);
|
|
869
|
+
- (this behavior will be reworked with another algorithm in future);
|
|
864
870
|
- each lock will be released with the next formula:
|
|
865
871
|
- `lock position with reverse numbering` * `ttl`
|
|
866
872
|
- (positions exmaple: ["a", "b", "c"] => "a" position is 3, "b" position is 2, "c" position is 1);
|
|
867
|
-
- this means
|
|
873
|
+
- this means that in case of 3 locks (`lock_series("x", "y", "z", ttl: 5_000`) with `5 seconds TTL` your locks will be with the next TTL:
|
|
868
874
|
- `"x"` - 15 seconds
|
|
869
875
|
- `"y"` - 10 seconds
|
|
870
876
|
- `"z"` - 5 seconds
|
|
871
877
|
- when your block of code has completed their execution - all locks will be released immediatly;
|
|
872
|
-
- if you did not pass a block - all locks will be released with their forumla-based
|
|
878
|
+
- if you did not pass a block - all locks will be released with their forumla-based TTL described above;
|
|
873
879
|
- **HOW WILL THIS CASE WORK IN FUTURE RELESAE**: all locks will have the same TTL (`5 seconds` for our example, not `15/10/5 seconds`);
|
|
874
880
|
|
|
875
|
-
|
|
881
|
+
##### How to use:
|
|
882
|
+
|
|
883
|
+
- method signature is the same as the `lock` method;
|
|
876
884
|
|
|
877
885
|
```ruby
|
|
878
886
|
# typical logic-oriented way
|
|
879
887
|
client.lock_series("a", "b", "c") { ...some_code... }
|
|
880
888
|
|
|
881
|
-
# result-oriented way
|
|
889
|
+
# result-oriented way:
|
|
890
|
+
# - (block is passed)
|
|
882
891
|
detailed_result = client.lock_series('x', 'y', 'z', detailed_result: true) { 1 + 2 }
|
|
883
892
|
detailed_result # =>
|
|
884
893
|
{
|
|
885
894
|
yield_result: 3, # result of your block of code
|
|
895
|
+
lock_release_strategy: :immediate_release_after_yield, # (block is passed)
|
|
886
896
|
locks_released_at: 1769506100.676884, # (instrumentation) release time, epoch
|
|
887
897
|
locks_acq_time: 7.0, # (instrumentation) time spent to acquire all locks, milliseconds
|
|
888
|
-
locks_hold_time: 0.65, # (instrumentation) lock hold period, milliseconds
|
|
898
|
+
locks_hold_time: 0.65, # (instrumentation) lock series hold period (hold preiod of all required locks), milliseconds
|
|
899
|
+
lock_series: ["x", "y", "z"], # your locks
|
|
900
|
+
rql_lock_series: ["rql:lock:x", "rql:lock:y", "rql:lock:z"] # internal RQL lock-keys of your locks
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
# - (block is not passed)
|
|
904
|
+
detailed_result = client.lock_series('x', 'y', 'z', detailed_result: true)
|
|
905
|
+
detailed_result # =>
|
|
906
|
+
{
|
|
907
|
+
yield_result: nil, # block is not given - nothing to return
|
|
908
|
+
lock_release_strategy: :redis_key_ttl, # block is not given - locks are living in redis with their TTL
|
|
909
|
+
locks_released_at: nil, # (instrumentation) # block is not given - locks are living in redis with their TTL
|
|
910
|
+
locks_acq_time: 7.0, # (instrumentation) time spent to acquire all locks, milliseconds
|
|
911
|
+
locks_hold_time: nil, # (instrumentation) # block is not given - locks are living in redis with their TTL
|
|
889
912
|
lock_series: ["x", "y", "z"], # your locks
|
|
890
913
|
rql_lock_series: ["rql:lock:x", "rql:lock:y", "rql:lock:z"] # internal RQL lock-keys of your locks
|
|
891
914
|
}
|
|
892
915
|
```
|
|
893
916
|
|
|
894
|
-
|
|
917
|
+
```ruby
|
|
918
|
+
# (failed lock obtainig) when lock series can not be obtained for some reasons
|
|
919
|
+
# for example: one of required lock in series is still obtained and can not be obtained now (and all retries are exhausted)
|
|
920
|
+
|
|
921
|
+
# - lock 'a' is obtained with long ttl
|
|
922
|
+
client.lock('a', ttl: 10_000_000)
|
|
923
|
+
|
|
924
|
+
# - try to bobtain series of locks with `a` inside the series (`a` can not be obtained for now)
|
|
925
|
+
client.lock_seires('c', 'a', 'b') # ... `a` is still obtained
|
|
926
|
+
# =>
|
|
927
|
+
{
|
|
928
|
+
ok: false,
|
|
929
|
+
result: {
|
|
930
|
+
error: :failed_to_acquire_lock_series,
|
|
931
|
+
detailed_errors: { 'a' => { ok: false, result: :retry_limit_reached } },
|
|
932
|
+
lock_series: ["c", "a", "b"],
|
|
933
|
+
acquired_locks: ["c"],
|
|
934
|
+
missing_locks: ["a", "b"],
|
|
935
|
+
failed_on_lock: ["a"],
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
```
|
|
939
|
+
|
|
940
|
+
##### New instrumentaiton events and logs:
|
|
895
941
|
|
|
896
942
|
```ruby
|
|
897
943
|
# NEW instrumentation events (examples)
|
|
898
|
-
"redis_queued_locks.
|
|
899
|
-
"redis_queued_locks.
|
|
944
|
+
"redis_queued_locks.lock_series_obtained" => # {lock_keys: ["rql:lock:s", "rql:lock:t", "rql:lock:u"], ttl: 5000, acq_id: "rql:acq:4486/1696/1704/1712/e6fd0da7991e4303", hst_id: "rql:hst:4486/1696/1712/e6fd0da7991e4303", ts: "2026-01-28 22:05:06 +0300", acq_time: 2.61, instrument: nil}
|
|
945
|
+
"redis_queued_locks.lock_series_hold_and_release" => # {lock_keys: ["rql:lock:x", "rql:lock:y", "rql:lock:z"], hold_time: 0.29, ttl: 5000, acq_id: "rql:acq:4486/1696/1704/1712/e6fd0da7991e4303", hst_id: "rql:hst:4486/1696/1712/e6fd0da7991e4303", ts: 1769627106.4717052, acq_time: 4.26, instrument: nil}
|
|
900
946
|
```
|
|
901
947
|
|
|
902
948
|
```shell
|
|
903
949
|
# NEW logs (examples)
|
|
904
|
-
[redis_queued_locks.start_lock_series_obtaining] lock_keys => '["rql:lock:
|
|
905
|
-
[redis_queued_locks.lock_series_obtained] lock_keys => '["rql:lock:
|
|
906
|
-
[redis_queued_locks.expire_lock_series] lock_keys => '["rql:lock:x", "rql:lock:y", "rql:lock:z"]' queue_ttl => 15 acq_id => 'rql:acq:
|
|
950
|
+
[redis_queued_locks.start_lock_series_obtaining] lock_keys => '["rql:lock:a", "rql:lock:b"]'queue_ttl => 15 acq_id => 'rql:acq:4486/1696/1704/1712/e6fd0da7991e4303' hst_id => 'rql:hst:4486/1696/1712/e6fd0da7991e4303' acs_strat => 'queued'
|
|
951
|
+
[redis_queued_locks.lock_series_obtained] lock_keys => '["rql:lock:a", "rql:lock:b"]' queue_ttl => 15 acq_id => 'rql:acq:4486/1696/1704/1712/e6fd0da7991e4303' hst_id => 'rql:hst:4486/1696/1712/e6fd0da7991e4303' acs_strat => 'queued' acq_time => 2.55 (ms)
|
|
952
|
+
[redis_queued_locks.expire_lock_series] lock_keys => '["rql:lock:x", "rql:lock:y", "rql:lock:z"]' queue_ttl => 15 acq_id => 'rql:acq:4486/1696/1704/1712/e6fd0da7991e4303' hst_id => 'rql:hst:4486/1696/1712/e6fd0da7991e4303' acs_strat => 'queued'
|
|
907
953
|
```
|
|
908
954
|
|
|
909
955
|
----
|
|
@@ -915,7 +961,7 @@ detailed_result # =>
|
|
|
915
961
|
For more details see `lock_series` [docs](#lock_series---poc-acquire-a-series-of-locks)
|
|
916
962
|
|
|
917
963
|
```ruby
|
|
918
|
-
client.lock_series!("x", "y", "z")
|
|
964
|
+
client.lock_series!("x", "y", "z") { ...some_code... }
|
|
919
965
|
```
|
|
920
966
|
|
|
921
967
|
----
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# @api private
|
|
4
|
-
# @since 1.
|
|
5
|
-
# rubocop:disable Metrics/ModuleLength
|
|
4
|
+
# @since 1.7.0
|
|
6
5
|
module RedisQueuedLocks::Acquirer::AcquireLock::InstrVisitor
|
|
7
6
|
class << self
|
|
8
7
|
# @param instrumenter [#notify]
|
|
@@ -163,27 +162,5 @@ module RedisQueuedLocks::Acquirer::AcquireLock::InstrVisitor
|
|
|
163
162
|
hold_time:, ttl:, acq_id:, hst_id:, ts:, lock_key:, acq_time:, instrument:
|
|
164
163
|
}) rescue nil
|
|
165
164
|
end
|
|
166
|
-
|
|
167
|
-
# NOTE: Lock Series PoC
|
|
168
|
-
# @api private
|
|
169
|
-
# @since 1.16.0
|
|
170
|
-
def lock_series_hold_and_release( # steep:ignore
|
|
171
|
-
instrumenter,
|
|
172
|
-
instr_sampled,
|
|
173
|
-
lock_keys,
|
|
174
|
-
ttl,
|
|
175
|
-
acq_id,
|
|
176
|
-
hst_id,
|
|
177
|
-
ts,
|
|
178
|
-
acq_time,
|
|
179
|
-
hold_time,
|
|
180
|
-
instrument
|
|
181
|
-
)
|
|
182
|
-
return unless instr_sampled
|
|
183
|
-
instrumenter.notify('redis_queued_locks.lock_series_hold_and_release', {
|
|
184
|
-
hold_time:, ttl:, acq_id:, hst_id:, ts:, lock_keys:, acq_time:, instrument:
|
|
185
|
-
}) # rescue nil
|
|
186
|
-
end
|
|
187
165
|
end
|
|
188
166
|
end
|
|
189
|
-
# rubocop:enable Metrics/ModuleLength
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
# @api private
|
|
4
|
-
# @since 1.
|
|
4
|
+
# @since 1.7.0
|
|
5
5
|
# rubocop:disable Metrics/ModuleLength
|
|
6
6
|
module RedisQueuedLocks::Acquirer::AcquireLock::LogVisitor
|
|
7
7
|
# rubocop:disable Metrics/ClassLength
|
|
@@ -39,30 +39,6 @@ module RedisQueuedLocks::Acquirer::AcquireLock::LogVisitor
|
|
|
39
39
|
end rescue nil
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
# NOTE: Lock Series PoC
|
|
43
|
-
# @api private
|
|
44
|
-
# @since 1.16.0
|
|
45
|
-
def start_lock_series_obtaining( # steep:ignore
|
|
46
|
-
logger,
|
|
47
|
-
log_sampled,
|
|
48
|
-
lock_keys,
|
|
49
|
-
queue_ttl,
|
|
50
|
-
acquirer_id,
|
|
51
|
-
host_id,
|
|
52
|
-
access_strategy
|
|
53
|
-
)
|
|
54
|
-
return unless log_sampled
|
|
55
|
-
|
|
56
|
-
logger.debug do
|
|
57
|
-
"[redis_queued_locks.start_lock_series_obtaining] " \
|
|
58
|
-
"lock_keys => '#{lock_keys.inspect}'" \
|
|
59
|
-
"queue_ttl => #{queue_ttl} " \
|
|
60
|
-
"acq_id => '#{acquirer_id}' " \
|
|
61
|
-
"hst_id => '#{host_id}' " \
|
|
62
|
-
"acs_strat => '#{access_strategy}'"
|
|
63
|
-
end # rescue nil
|
|
64
|
-
end
|
|
65
|
-
|
|
66
42
|
# @param logger [::Logger,#debug]
|
|
67
43
|
# @param log_sampled [Boolean]
|
|
68
44
|
# @param lock_key [String]
|
|
@@ -236,32 +212,6 @@ module RedisQueuedLocks::Acquirer::AcquireLock::LogVisitor
|
|
|
236
212
|
"acq_time => #{acq_time} (ms)"
|
|
237
213
|
end rescue nil
|
|
238
214
|
end
|
|
239
|
-
|
|
240
|
-
# NOTE: Lock Series PoC
|
|
241
|
-
# @api private
|
|
242
|
-
# @since 1.16.0
|
|
243
|
-
def lock_series_obtained( # steep:ignore
|
|
244
|
-
logger,
|
|
245
|
-
log_sampled,
|
|
246
|
-
lock_keys,
|
|
247
|
-
queue_ttl,
|
|
248
|
-
acquirer_id,
|
|
249
|
-
host_id,
|
|
250
|
-
acq_time,
|
|
251
|
-
access_strategy
|
|
252
|
-
)
|
|
253
|
-
return unless log_sampled
|
|
254
|
-
|
|
255
|
-
logger.debug do
|
|
256
|
-
"[redis_queued_locks.lock_series_obtained] " \
|
|
257
|
-
"lock_keys => '#{lock_keys.inspect}' " \
|
|
258
|
-
"queue_ttl => #{queue_ttl} " \
|
|
259
|
-
"acq_id => '#{acquirer_id}' " \
|
|
260
|
-
"hst_id => '#{host_id}' " \
|
|
261
|
-
"acs_strat => '#{access_strategy}' " \
|
|
262
|
-
"acq_time => #{acq_time} (ms)"
|
|
263
|
-
end # rescue nil
|
|
264
|
-
end
|
|
265
215
|
end
|
|
266
216
|
# rubocop:enable Metrics/ClassLength
|
|
267
217
|
end
|
|
@@ -37,30 +37,6 @@ module RedisQueuedLocks::Acquirer::AcquireLock::YieldExpire::LogVisitor
|
|
|
37
37
|
end rescue nil
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
# NOTE: Lock Series PoC
|
|
41
|
-
# @api private
|
|
42
|
-
# @since 1.16.0
|
|
43
|
-
def expire_lock_series( # steep:ignore
|
|
44
|
-
logger,
|
|
45
|
-
log_sampled,
|
|
46
|
-
lock_series,
|
|
47
|
-
queue_ttl,
|
|
48
|
-
acquirer_id,
|
|
49
|
-
host_id,
|
|
50
|
-
access_strategy
|
|
51
|
-
)
|
|
52
|
-
return unless log_sampled
|
|
53
|
-
|
|
54
|
-
logger.debug do
|
|
55
|
-
"[redis_queued_locks.expire_lock_series] " \
|
|
56
|
-
"lock_keys => '#{lock_series.inspect}' " \
|
|
57
|
-
"queue_ttl => #{queue_ttl} " \
|
|
58
|
-
"acq_id => '#{acquirer_id}' " \
|
|
59
|
-
"hst_id => '#{host_id}' " \
|
|
60
|
-
"acs_strat => '#{access_strategy}'"
|
|
61
|
-
end rescue nil
|
|
62
|
-
end
|
|
63
|
-
|
|
64
40
|
# @param logger [::Logger,#debug]
|
|
65
41
|
# @param log_sampled [Boolean]
|
|
66
42
|
# @param lock_key [String]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# NOTE: Lock Series PoC
|
|
4
|
+
# steep:ignore
|
|
5
|
+
# @api private
|
|
6
|
+
# @since 1.16.1
|
|
7
|
+
module RedisQueuedLocks::Acquirer::LockSeriesPoC::InstrVisitor # steep:ignore
|
|
8
|
+
class << self
|
|
9
|
+
# NOTE: Lock Series PoC
|
|
10
|
+
# @api private
|
|
11
|
+
# @since 1.16.1
|
|
12
|
+
def lock_series_obtained( # steep:ignore
|
|
13
|
+
instrumenter,
|
|
14
|
+
instr_sampled,
|
|
15
|
+
lock_keys,
|
|
16
|
+
ttl,
|
|
17
|
+
acq_id,
|
|
18
|
+
hst_id,
|
|
19
|
+
ts,
|
|
20
|
+
acq_time,
|
|
21
|
+
instrument
|
|
22
|
+
)
|
|
23
|
+
return unless instr_sampled
|
|
24
|
+
instrumenter.notify('redis_queued_locks.lock_series_obtained', {
|
|
25
|
+
lock_keys:, ttl:, acq_id:, hst_id:, ts:, acq_time:, instrument:
|
|
26
|
+
}) rescue nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# NOTE: Lock Series PoC
|
|
30
|
+
# @api private
|
|
31
|
+
# @since 1.16.1
|
|
32
|
+
def lock_series_hold_and_release( # steep:ignore
|
|
33
|
+
instrumenter,
|
|
34
|
+
instr_sampled,
|
|
35
|
+
lock_keys,
|
|
36
|
+
ttl,
|
|
37
|
+
acq_id,
|
|
38
|
+
hst_id,
|
|
39
|
+
ts,
|
|
40
|
+
acq_time,
|
|
41
|
+
hold_time,
|
|
42
|
+
instrument
|
|
43
|
+
)
|
|
44
|
+
return unless instr_sampled
|
|
45
|
+
instrumenter.notify('redis_queued_locks.lock_series_hold_and_release', {
|
|
46
|
+
lock_keys:, hold_time:, ttl:, acq_id:, hst_id:, ts:, acq_time:, instrument:
|
|
47
|
+
}) # rescue nil
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
# steep:ignore
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# NOTE: Lock Series PoC
|
|
4
|
+
# steep:ignore
|
|
5
|
+
# @api private
|
|
6
|
+
# @since 1.16.1
|
|
7
|
+
module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
8
|
+
class << self
|
|
9
|
+
# NOTE: Lock Series PoC
|
|
10
|
+
# @api private
|
|
11
|
+
# @since 1.16.0
|
|
12
|
+
def start_lock_series_obtaining( # steep:ignore
|
|
13
|
+
logger,
|
|
14
|
+
log_sampled,
|
|
15
|
+
lock_keys,
|
|
16
|
+
queue_ttl,
|
|
17
|
+
acquirer_id,
|
|
18
|
+
host_id,
|
|
19
|
+
access_strategy
|
|
20
|
+
)
|
|
21
|
+
return unless log_sampled
|
|
22
|
+
|
|
23
|
+
logger.debug do
|
|
24
|
+
"[redis_queued_locks.start_lock_series_obtaining] " \
|
|
25
|
+
"lock_keys => '#{lock_keys.inspect}'" \
|
|
26
|
+
"queue_ttl => #{queue_ttl} " \
|
|
27
|
+
"acq_id => '#{acquirer_id}' " \
|
|
28
|
+
"hst_id => '#{host_id}' " \
|
|
29
|
+
"acs_strat => '#{access_strategy}'"
|
|
30
|
+
end # rescue nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# NOTE: Lock Series PoC
|
|
34
|
+
# @api private
|
|
35
|
+
# @since 1.16.0
|
|
36
|
+
def lock_series_obtained( # steep:ignore
|
|
37
|
+
logger,
|
|
38
|
+
log_sampled,
|
|
39
|
+
lock_keys,
|
|
40
|
+
queue_ttl,
|
|
41
|
+
acquirer_id,
|
|
42
|
+
host_id,
|
|
43
|
+
acq_time,
|
|
44
|
+
access_strategy
|
|
45
|
+
)
|
|
46
|
+
return unless log_sampled
|
|
47
|
+
|
|
48
|
+
logger.debug do
|
|
49
|
+
"[redis_queued_locks.lock_series_obtained] " \
|
|
50
|
+
"lock_keys => '#{lock_keys.inspect}' " \
|
|
51
|
+
"queue_ttl => #{queue_ttl} " \
|
|
52
|
+
"acq_id => '#{acquirer_id}' " \
|
|
53
|
+
"hst_id => '#{host_id}' " \
|
|
54
|
+
"acs_strat => '#{access_strategy}' " \
|
|
55
|
+
"acq_time => #{acq_time} (ms)"
|
|
56
|
+
end # rescue nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# NOTE: Lock Series PoC
|
|
60
|
+
# @api private
|
|
61
|
+
# @since 1.16.0
|
|
62
|
+
def expire_lock_series( # steep:ignore
|
|
63
|
+
logger,
|
|
64
|
+
log_sampled,
|
|
65
|
+
lock_series,
|
|
66
|
+
queue_ttl,
|
|
67
|
+
acquirer_id,
|
|
68
|
+
host_id,
|
|
69
|
+
access_strategy
|
|
70
|
+
)
|
|
71
|
+
return unless log_sampled
|
|
72
|
+
|
|
73
|
+
logger.debug do
|
|
74
|
+
"[redis_queued_locks.expire_lock_series] " \
|
|
75
|
+
"lock_keys => '#{lock_series.inspect}' " \
|
|
76
|
+
"queue_ttl => #{queue_ttl} " \
|
|
77
|
+
"acq_id => '#{acquirer_id}' " \
|
|
78
|
+
"hst_id => '#{host_id}' " \
|
|
79
|
+
"acs_strat => '#{access_strategy}'"
|
|
80
|
+
end rescue nil
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -6,12 +6,16 @@
|
|
|
6
6
|
# @api private
|
|
7
7
|
# @since 1.16.0
|
|
8
8
|
module RedisQueuedLocks::Acquirer::LockSeriesPoC # steep:ignore
|
|
9
|
-
|
|
9
|
+
require_relative 'lock_series_poc/log_visitor'
|
|
10
|
+
require_relative 'lock_series_poc/instr_visitor'
|
|
11
|
+
|
|
12
|
+
# @sine 1.16.0
|
|
10
13
|
extend RedisQueuedLocks::Acquirer::AcquireLock::YieldExpire
|
|
11
14
|
|
|
12
15
|
class << self
|
|
13
16
|
# @api private
|
|
14
17
|
# @since 1.16.0
|
|
18
|
+
# @version 1.16.1
|
|
15
19
|
def lock_series_poc( # steep:ignore
|
|
16
20
|
redis,
|
|
17
21
|
lock_names,
|
|
@@ -123,7 +127,7 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC # steep:ignore
|
|
|
123
127
|
identity
|
|
124
128
|
)
|
|
125
129
|
|
|
126
|
-
RedisQueuedLocks::Acquirer::
|
|
130
|
+
RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor.start_lock_series_obtaining( # steep:ignore
|
|
127
131
|
logger, log_sampled, lock_keys_for_instrumentation,
|
|
128
132
|
queue_ttl, acquirer_id_for_instrumentation, host_id_for_instrumentation, access_strategy
|
|
129
133
|
)
|
|
@@ -202,13 +206,19 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC # steep:ignore
|
|
|
202
206
|
if (successfully_acquired_locks.size == lock_names.size && (successfully_acquired_locks.all? { |res| res[:ok] }))
|
|
203
207
|
acq_end_time = RedisQueuedLocks::Utilities.clock_gettime
|
|
204
208
|
acq_time = ((acq_end_time - acq_start_time) / 1_000.0).ceil(2)
|
|
209
|
+
ts = Time.now.to_s
|
|
205
210
|
|
|
206
|
-
RedisQueuedLocks::Acquirer::
|
|
211
|
+
RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor.lock_series_obtained( # steep:ignore
|
|
207
212
|
logger, log_sampled, lock_keys_for_instrumentation,
|
|
208
213
|
queue_ttl, acquirer_id_for_instrumentation, host_id_for_instrumentation,
|
|
209
214
|
acq_time, access_strategy
|
|
210
215
|
)
|
|
211
216
|
|
|
217
|
+
RedisQueuedLocks::Acquirer::LockSeriesPoC::InstrVisitor.lock_series_obtained( # steep:ignore
|
|
218
|
+
instrumenter, instr_sampled, lock_keys_for_instrumentation,
|
|
219
|
+
ttl, acquirer_id_for_instrumentation, host_id_for_instrumentation, ts, acq_time, instrument
|
|
220
|
+
)
|
|
221
|
+
|
|
212
222
|
yield_time = RedisQueuedLocks::Utilities.clock_gettime
|
|
213
223
|
ttl_shift = (
|
|
214
224
|
(yield_time - acq_end_time) / 1_000.0 -
|
|
@@ -234,6 +244,8 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC # steep:ignore
|
|
|
234
244
|
&block
|
|
235
245
|
)
|
|
236
246
|
|
|
247
|
+
is_lock_manually_released = false
|
|
248
|
+
|
|
237
249
|
# expire locks manually
|
|
238
250
|
if block_given?
|
|
239
251
|
redis.with do |conn|
|
|
@@ -244,18 +256,19 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC # steep:ignore
|
|
|
244
256
|
end
|
|
245
257
|
end
|
|
246
258
|
end
|
|
259
|
+
is_lock_manually_released = true
|
|
247
260
|
end
|
|
248
261
|
|
|
249
262
|
rel_time = RedisQueuedLocks::Utilities.clock_gettime
|
|
250
263
|
hold_time = ((rel_time - acq_end_time) / 1_000.0).ceil(2)
|
|
251
264
|
ts = Time.now.to_f
|
|
252
265
|
|
|
253
|
-
RedisQueuedLocks::Acquirer::
|
|
266
|
+
RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor.expire_lock_series( # steep:ignore
|
|
254
267
|
logger, log_sampled, lock_keys_for_instrumentation,
|
|
255
268
|
queue_ttl, acquirer_id_for_instrumentation, host_id_for_instrumentation, access_strategy
|
|
256
|
-
)
|
|
269
|
+
) if is_lock_manually_released
|
|
257
270
|
|
|
258
|
-
RedisQueuedLocks::Acquirer::
|
|
271
|
+
RedisQueuedLocks::Acquirer::LockSeriesPoC::InstrVisitor.lock_series_hold_and_release( # steep:ignore
|
|
259
272
|
instrumenter,
|
|
260
273
|
instr_sampled,
|
|
261
274
|
lock_keys_for_instrumentation,
|
|
@@ -266,14 +279,15 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC # steep:ignore
|
|
|
266
279
|
acq_time,
|
|
267
280
|
hold_time,
|
|
268
281
|
instrument
|
|
269
|
-
)
|
|
282
|
+
) if is_lock_manually_released
|
|
270
283
|
|
|
271
284
|
if detailed_result
|
|
272
285
|
{
|
|
273
286
|
yield_result: yield_result,
|
|
274
|
-
|
|
287
|
+
locks_release_strategy: block_given? ? :immediate_release_after_yield : :redis_key_ttl,
|
|
288
|
+
locks_released_at: block_given? ? ts : nil,
|
|
275
289
|
locks_acq_time: acq_time,
|
|
276
|
-
locks_hold_time: hold_time,
|
|
290
|
+
locks_hold_time: is_lock_manually_released ? hold_time : nil,
|
|
277
291
|
lock_series: lock_names,
|
|
278
292
|
rql_lock_series: lock_keys_for_instrumentation
|
|
279
293
|
}
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: redis_queued_locks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.16.
|
|
4
|
+
version: 1.16.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rustam Ibragimov
|
|
@@ -66,6 +66,8 @@ files:
|
|
|
66
66
|
- lib/redis_queued_locks/acquirer/keys.rb
|
|
67
67
|
- lib/redis_queued_locks/acquirer/lock_info.rb
|
|
68
68
|
- lib/redis_queued_locks/acquirer/lock_series_poc.rb
|
|
69
|
+
- lib/redis_queued_locks/acquirer/lock_series_poc/instr_visitor.rb
|
|
70
|
+
- lib/redis_queued_locks/acquirer/lock_series_poc/log_visitor.rb
|
|
69
71
|
- lib/redis_queued_locks/acquirer/locks.rb
|
|
70
72
|
- lib/redis_queued_locks/acquirer/queue_info.rb
|
|
71
73
|
- lib/redis_queued_locks/acquirer/queues.rb
|