redis_queued_locks 1.20.0 → 1.22.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/.claude/project-overview.md +249 -36
- data/.claude/rules/acquirer.md +16 -14
- data/.claude/rules/arguments.md +2 -2
- data/.claude/rules/changelog.md +27 -0
- data/.claude/rules/git.md +1 -1
- data/.claude/rules/logic.md +34 -13
- data/.claude/rules/swarm.md +4 -5
- data/.claude/rules/tests.md +9 -6
- data/.claude/rules/type-checking.md +13 -14
- data/.claude/rules/visitors.md +13 -14
- data/.claude/skills/rql-code-review/SKILL.md +134 -43
- data/CHANGELOG.md +105 -125
- data/CLAUDE.md +11 -9
- data/README.md +501 -136
- data/Rakefile +11 -0
- data/lib/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rb +1 -0
- data/lib/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rb +68 -10
- data/lib/redis_queued_locks/acquirer/acquire_lock/log_visitor.rb +82 -15
- data/lib/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rb +92 -14
- data/lib/redis_queued_locks/acquirer/acquire_lock/try_to_lock.rb +441 -63
- data/lib/redis_queued_locks/acquirer/acquire_lock/with_acq_timeout.rb +2 -2
- data/lib/redis_queued_locks/acquirer/acquire_lock/yield_expire/log_visitor.rb +1 -0
- data/lib/redis_queued_locks/acquirer/acquire_lock/yield_expire.rb +5 -5
- data/lib/redis_queued_locks/acquirer/acquire_lock.rb +176 -39
- data/lib/redis_queued_locks/acquirer/clear_dead_requests.rb +322 -49
- data/lib/redis_queued_locks/acquirer/extend_lock_ttl.rb +125 -13
- data/lib/redis_queued_locks/acquirer/is_locked.rb +0 -1
- data/lib/redis_queued_locks/acquirer/is_queued.rb +0 -1
- data/lib/redis_queued_locks/acquirer/keys.rb +16 -3
- data/lib/redis_queued_locks/acquirer/lock_info.rb +31 -39
- data/lib/redis_queued_locks/acquirer/lock_series_poc/instr_visitor.rb +11 -5
- data/lib/redis_queued_locks/acquirer/lock_series_poc/log_visitor.rb +20 -10
- data/lib/redis_queued_locks/acquirer/lock_series_poc.rb +105 -36
- data/lib/redis_queued_locks/acquirer/locks.rb +32 -11
- data/lib/redis_queued_locks/acquirer/queue_info.rb +30 -8
- data/lib/redis_queued_locks/acquirer/queues.rb +26 -6
- data/lib/redis_queued_locks/acquirer/reindex_locks.rb +117 -4
- data/lib/redis_queued_locks/acquirer/release_all_locks.rb +37 -6
- data/lib/redis_queued_locks/acquirer/release_lock.rb +33 -7
- data/lib/redis_queued_locks/acquirer/release_locks_of.rb +45 -6
- data/lib/redis_queued_locks/acquirer/release_read_lock.rb +22 -3
- data/lib/redis_queued_locks/client.rb +140 -56
- data/lib/redis_queued_locks/config.rb +105 -14
- data/lib/redis_queued_locks/errors.rb +34 -4
- data/lib/redis_queued_locks/instrument/sampler.rb +4 -7
- data/lib/redis_queued_locks/logging/sampler.rb +4 -8
- data/lib/redis_queued_locks/resource.rb +137 -12
- data/lib/redis_queued_locks/swarm/flush_zombies.rb +1 -0
- data/lib/redis_queued_locks/swarm/redis_client_builder.rb +8 -4
- data/lib/redis_queued_locks/swarm/swarm_element/threaded.rb +8 -6
- data/lib/redis_queued_locks/swarm/zombie_info.rb +6 -2
- data/lib/redis_queued_locks/swarm.rb +86 -5
- data/lib/redis_queued_locks/utilities.rb +1 -1
- data/lib/redis_queued_locks/version.rb +2 -2
- data/rbs_collection.lock.yaml +4 -0
- data/rbs_collection.yaml +2 -1
- data/sig/manifest.yml +1 -0
- data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rbs +2 -2
- data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue.rbs +2 -2
- data/sig/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rbs +25 -5
- data/sig/redis_queued_locks/acquirer/acquire_lock/log_visitor.rbs +32 -12
- data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rbs +61 -40
- data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock.rbs +59 -11
- data/sig/redis_queued_locks/acquirer/acquire_lock/{yield_with_expire → yield_expire}/log_visitor.rbs +4 -4
- data/sig/redis_queued_locks/acquirer/acquire_lock/yield_expire.rbs +4 -4
- data/sig/redis_queued_locks/acquirer/acquire_lock.rbs +6 -4
- data/sig/redis_queued_locks/acquirer/clear_dead_requests.rbs +23 -1
- data/sig/redis_queued_locks/acquirer/extend_lock_ttl.rbs +16 -3
- data/sig/redis_queued_locks/acquirer/queues.rbs +1 -1
- data/sig/redis_queued_locks/acquirer/reindex_locks.rbs +22 -1
- data/sig/redis_queued_locks/acquirer/release_lock.rbs +3 -2
- data/sig/redis_queued_locks/acquirer/release_read_lock.rbs +1 -1
- data/sig/redis_queued_locks/client.rbs +24 -10
- data/sig/redis_queued_locks/config.rbs +54 -1
- data/sig/redis_queued_locks/errors.rbs +5 -2
- data/sig/redis_queued_locks/instrument/sampler.rbs +3 -3
- data/sig/redis_queued_locks/instrument/void_notifier.rbs +3 -1
- data/sig/redis_queued_locks/logging/sampler.rbs +3 -3
- data/sig/redis_queued_locks/resource.rbs +23 -13
- data/sig/redis_queued_locks/swarm/swarm_element/threaded.rbs +1 -1
- data/sig/redis_queued_locks/utilities.rbs +2 -1
- data/sig/redis_queued_locks.rbs +7 -0
- data/sig/vendor/redis_client.rbs +1 -0
- metadata +4 -3
- /data/sig/redis_queued_locks/{acquier.rbs → acquirer.rbs} +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# @api private
|
|
4
4
|
# @since 1.0.0
|
|
5
|
-
# @version 1.
|
|
5
|
+
# @version 1.21.0
|
|
6
6
|
# rubocop:disable Metrics/ModuleLength
|
|
7
7
|
module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
8
8
|
# @return [String]
|
|
@@ -14,11 +14,18 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
14
14
|
return redis.call("PEXPIRE", KEYS[1], new_lock_pttl);
|
|
15
15
|
LUA_SCRIPT
|
|
16
16
|
|
|
17
|
+
# @since 1.21.0
|
|
18
|
+
extend RedisQueuedLocks::Utilities
|
|
19
|
+
|
|
17
20
|
# rubocop:disable Metrics/ClassLength
|
|
18
21
|
class << self
|
|
22
|
+
# Extends the lock TTL and reports the operation (one log and one instrumentation event
|
|
23
|
+
# `redis_queued_locks.extend_lock_ttl` with the time of the whole operation).
|
|
24
|
+
#
|
|
19
25
|
# @param redis_client [RedisClient]
|
|
20
26
|
# @param lock_name [String]
|
|
21
27
|
# @param milliseconds [Integer]
|
|
28
|
+
# How many milliseconds should be added: a positive Integer.
|
|
22
29
|
# @param read_write_mode [Symbol]
|
|
23
30
|
# - `:write` - extends the write lock (of any acquirer);
|
|
24
31
|
# - `:read` - extends the read lock of the given acquirer (other read locks are not affected)
|
|
@@ -45,7 +52,7 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
45
52
|
#
|
|
46
53
|
# @api private
|
|
47
54
|
# @since 1.0.0
|
|
48
|
-
# @version 1.
|
|
55
|
+
# @version 1.21.0
|
|
49
56
|
# rubocop:disable Metrics/MethodLength
|
|
50
57
|
def extend_lock_ttl(
|
|
51
58
|
redis_client,
|
|
@@ -67,7 +74,9 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
67
74
|
instr_sampler,
|
|
68
75
|
instr_sample_this
|
|
69
76
|
)
|
|
70
|
-
|
|
77
|
+
case read_write_mode # NOTE: (steep) case/when narrows `Symbol` to `RQL::readWriteMode` below
|
|
78
|
+
when :read, :write then nil
|
|
79
|
+
else
|
|
71
80
|
raise(
|
|
72
81
|
RedisQueuedLocks::ArgumentError,
|
|
73
82
|
"`:read_write_mode` argument should be `:read` or `:write`, " \
|
|
@@ -75,16 +84,105 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
75
84
|
)
|
|
76
85
|
end
|
|
77
86
|
|
|
87
|
+
# NOTE: a non-positive value would decrease the lock ttl or delete the lock;
|
|
88
|
+
if !milliseconds.is_a?(::Integer) || milliseconds <= 0
|
|
89
|
+
raise(
|
|
90
|
+
RedisQueuedLocks::ArgumentError,
|
|
91
|
+
"`milliseconds` argument should be a positive Integer, got #{milliseconds.inspect}."
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
if read_write_mode == :read && all_read_locks != true && all_read_locks != false
|
|
96
|
+
raise(
|
|
97
|
+
RedisQueuedLocks::ArgumentError,
|
|
98
|
+
"`:all_read_locks` argument should be a boolean, got #{all_read_locks.inspect}."
|
|
99
|
+
)
|
|
100
|
+
end
|
|
101
|
+
|
|
78
102
|
lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
|
|
79
103
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
104
|
+
ext_start_time = clock_gettime
|
|
105
|
+
result = fully_extend_lock_ttl(
|
|
106
|
+
redis_client, lock_name, lock_key, milliseconds, read_write_mode, all_read_locks,
|
|
107
|
+
acquirer_id, lock_index_enabled
|
|
108
|
+
)
|
|
109
|
+
time_at = Time.now.to_f
|
|
110
|
+
ext_end_time = clock_gettime
|
|
111
|
+
ext_time = ((ext_end_time - ext_start_time) / 1_000.0).ceil(2)
|
|
112
|
+
ext_result = result[:result]
|
|
113
|
+
extended_locks_count = ext_result.is_a?(::Hash) ? ext_result[:extended_locks_count] : 0
|
|
114
|
+
|
|
115
|
+
log_sampled = RedisQueuedLocks::Logging.should_log?(
|
|
116
|
+
log_sampling_enabled,
|
|
117
|
+
log_sample_this,
|
|
118
|
+
log_sampling_percent,
|
|
119
|
+
log_sampler
|
|
120
|
+
)
|
|
121
|
+
instr_sampled = RedisQueuedLocks::Instrument.should_instrument?(
|
|
122
|
+
instr_sampling_enabled,
|
|
123
|
+
instr_sample_this,
|
|
124
|
+
instr_sampling_percent,
|
|
125
|
+
instr_sampler
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
run_non_critical do
|
|
129
|
+
logger.debug do
|
|
130
|
+
"[redis_queued_locks.extend_lock_ttl] " \
|
|
131
|
+
"lock_key => '#{lock_key}' " \
|
|
132
|
+
"rw_mode => '#{read_write_mode}' " \
|
|
133
|
+
"all_read_locks => #{all_read_locks} " \
|
|
134
|
+
"ext_ttl => #{milliseconds} " \
|
|
135
|
+
"extended_locks_count => #{extended_locks_count} " \
|
|
136
|
+
"ext_time => #{ext_time} " \
|
|
137
|
+
"at => #{time_at}"
|
|
86
138
|
end
|
|
139
|
+
end if log_sampled
|
|
140
|
+
|
|
141
|
+
run_non_critical do
|
|
142
|
+
instrumenter.notify('redis_queued_locks.extend_lock_ttl', {
|
|
143
|
+
lock_key: lock_key,
|
|
144
|
+
rw_mode: read_write_mode,
|
|
145
|
+
all_read_locks: all_read_locks,
|
|
146
|
+
ext_ttl: milliseconds,
|
|
147
|
+
extended_locks_count: extended_locks_count,
|
|
148
|
+
ext_time: ext_time,
|
|
149
|
+
at: time_at,
|
|
150
|
+
instrument: instrument
|
|
151
|
+
})
|
|
152
|
+
end if instr_sampled
|
|
87
153
|
|
|
154
|
+
result
|
|
155
|
+
end
|
|
156
|
+
# rubocop:enable Metrics/MethodLength
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
# Extends the write lock, the read lock of the acquirer or all read locks of the lock.
|
|
161
|
+
#
|
|
162
|
+
# @param redis_client [RedisClient]
|
|
163
|
+
# @param lock_name [String]
|
|
164
|
+
# @param lock_key [String]
|
|
165
|
+
# @param milliseconds [Integer]
|
|
166
|
+
# @param read_write_mode [Symbol]
|
|
167
|
+
# @param all_read_locks [Boolean]
|
|
168
|
+
# @param acquirer_id [String]
|
|
169
|
+
# @param lock_index_enabled [Boolean]
|
|
170
|
+
# @return [Hash<Symbol,Boolean|Symbol|Hash<Symbol,Integer>>]
|
|
171
|
+
#
|
|
172
|
+
# @api private
|
|
173
|
+
# @since 1.21.0
|
|
174
|
+
# rubocop:disable Metrics/MethodLength
|
|
175
|
+
def fully_extend_lock_ttl(
|
|
176
|
+
redis_client,
|
|
177
|
+
lock_name,
|
|
178
|
+
lock_key,
|
|
179
|
+
milliseconds,
|
|
180
|
+
read_write_mode,
|
|
181
|
+
all_read_locks,
|
|
182
|
+
acquirer_id,
|
|
183
|
+
lock_index_enabled
|
|
184
|
+
)
|
|
185
|
+
if read_write_mode == :read
|
|
88
186
|
# NOTE: (RW) all live read locks of the lock
|
|
89
187
|
if all_read_locks
|
|
90
188
|
return extend_all_read_locks_ttl(
|
|
@@ -131,8 +229,6 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
131
229
|
end
|
|
132
230
|
# rubocop:enable Metrics/MethodLength
|
|
133
231
|
|
|
134
|
-
private
|
|
135
|
-
|
|
136
232
|
# Extends the live read lock of the acquirer:
|
|
137
233
|
# - the read lock expiration (readers registry score), the registry TTL and the read lock
|
|
138
234
|
# data TTL are extended;
|
|
@@ -149,7 +245,7 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
149
245
|
#
|
|
150
246
|
# @api private
|
|
151
247
|
# @since 1.18.0
|
|
152
|
-
# @version 1.
|
|
248
|
+
# @version 1.21.0
|
|
153
249
|
# rubocop:disable Metrics/MethodLength
|
|
154
250
|
def extend_read_lock_ttl(
|
|
155
251
|
redis_client,
|
|
@@ -191,6 +287,14 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
191
287
|
end
|
|
192
288
|
end
|
|
193
289
|
end
|
|
290
|
+
rescue RedisQueuedLocks::LockAcquirementIntermediateTimeoutError,
|
|
291
|
+
RedisQueuedLocks::TimedLockIntermediateTimeoutError,
|
|
292
|
+
::Timeout::ExitException
|
|
293
|
+
# NOTE: (timeouts) an interrupted WATCH block (the internal timeouts and the user's
|
|
294
|
+
# `Timeout.timeout` without an exception class): the closed connection drops the WATCH
|
|
295
|
+
# state (redis-client sends `UNWATCH` only on `StandardError`);
|
|
296
|
+
rconn.close
|
|
297
|
+
raise
|
|
194
298
|
end
|
|
195
299
|
|
|
196
300
|
# NOTE:
|
|
@@ -223,7 +327,7 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
223
327
|
#
|
|
224
328
|
# @api private
|
|
225
329
|
# @since 1.18.0
|
|
226
|
-
# @version 1.
|
|
330
|
+
# @version 1.21.0
|
|
227
331
|
# rubocop:disable Metrics/MethodLength
|
|
228
332
|
def extend_all_read_locks_ttl(
|
|
229
333
|
redis_client,
|
|
@@ -278,6 +382,14 @@ module RedisQueuedLocks::Acquirer::ExtendLockTTL
|
|
|
278
382
|
end
|
|
279
383
|
end
|
|
280
384
|
end
|
|
385
|
+
rescue RedisQueuedLocks::LockAcquirementIntermediateTimeoutError,
|
|
386
|
+
RedisQueuedLocks::TimedLockIntermediateTimeoutError,
|
|
387
|
+
::Timeout::ExitException
|
|
388
|
+
# NOTE: (timeouts) an interrupted WATCH block (the internal timeouts and the user's
|
|
389
|
+
# `Timeout.timeout` without an exception class): the closed connection drops the WATCH
|
|
390
|
+
# state (redis-client sends `UNWATCH` only on `StandardError`);
|
|
391
|
+
rconn.close
|
|
392
|
+
raise
|
|
281
393
|
end
|
|
282
394
|
|
|
283
395
|
# NOTE:
|
|
@@ -32,8 +32,17 @@ module RedisQueuedLocks::Acquirer::Keys
|
|
|
32
32
|
#
|
|
33
33
|
# @api private
|
|
34
34
|
# @since 1.0.0
|
|
35
|
-
# @version 1.
|
|
35
|
+
# @version 1.21.0
|
|
36
36
|
def keys(redis_client, scan_size:, lock_index_enabled:)
|
|
37
|
+
# NOTE: (arguments) the same range as the config key: zero/negative sizes fail SCAN/ZSCAN
|
|
38
|
+
# (`COUNT 0`) and the batching (`each_slice(0)`);
|
|
39
|
+
if !scan_size.is_a?(::Integer) || scan_size <= 0
|
|
40
|
+
raise(
|
|
41
|
+
RedisQueuedLocks::ArgumentError,
|
|
42
|
+
"`:scan_size` argument should be a positive Integer, got #{scan_size.inspect}."
|
|
43
|
+
)
|
|
44
|
+
end
|
|
45
|
+
|
|
37
46
|
Set.new.tap do |keyset|
|
|
38
47
|
# @type var keyset: Set[String]
|
|
39
48
|
if lock_index_enabled
|
|
@@ -125,7 +134,8 @@ module RedisQueuedLocks::Acquirer::Keys
|
|
|
125
134
|
|
|
126
135
|
# Iterates over the lock names of the lock index (one ZSCAN pass) in batches of `scan_size`
|
|
127
136
|
# lock names (batches are collected across ZSCAN pages). Expired lock names (not dropped from
|
|
128
|
-
# the index yet) are skipped: all their keys are expired
|
|
137
|
+
# the index yet) are skipped: all their keys are expired (`+inf` names, keys without TTL, never
|
|
138
|
+
# expire: see `RedisQueuedLocks::Resource.lock_index_score_expired?`).
|
|
129
139
|
#
|
|
130
140
|
# NOTE: each operation module iterates over the lock index by itself (duplicated on purpose:
|
|
131
141
|
# operation modules are independent of each other, see `Locks.each_lock_name_batch`);
|
|
@@ -138,6 +148,7 @@ module RedisQueuedLocks::Acquirer::Keys
|
|
|
138
148
|
#
|
|
139
149
|
# @api private
|
|
140
150
|
# @since 1.20.0
|
|
151
|
+
# @version 1.22.0
|
|
141
152
|
def each_lock_name_batch(redis_client, scan_size)
|
|
142
153
|
lock_index_time = RedisQueuedLocks::Resource.lock_index_time
|
|
143
154
|
# @type var lock_names: Array[String]
|
|
@@ -146,7 +157,9 @@ module RedisQueuedLocks::Acquirer::Keys
|
|
|
146
157
|
redis_client.zscan(
|
|
147
158
|
RedisQueuedLocks::Resource::LOCK_INDEX_KEY, count: scan_size
|
|
148
159
|
) do |lock_name, lock_index_score|
|
|
149
|
-
next if
|
|
160
|
+
next if RedisQueuedLocks::Resource.lock_index_score_expired?(
|
|
161
|
+
lock_index_score, lock_index_time
|
|
162
|
+
)
|
|
150
163
|
|
|
151
164
|
lock_names << lock_name
|
|
152
165
|
next if lock_names.size < scan_size
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# @api private
|
|
4
4
|
# @since 1.0.0
|
|
5
|
-
# @version 1.
|
|
5
|
+
# @version 1.18.0
|
|
6
6
|
module RedisQueuedLocks::Acquirer::LockInfo
|
|
7
7
|
class << self
|
|
8
8
|
# @param redis_client [RedisClient]
|
|
@@ -56,46 +56,38 @@ module RedisQueuedLocks::Acquirer::LockInfo
|
|
|
56
56
|
pipeline.call('ZRANGE', lock_readers_key, '0', '-1', 'WITHSCORES')
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
# NOTE: the result of MULTI-command is an array of results of each internal command
|
|
68
|
-
# - result[0] (HGETALL) (Hash<String,String>)
|
|
69
|
-
# => (will be mutated further with different value types)
|
|
70
|
-
# - result[1] (PTTL) (Integer)
|
|
71
|
-
# => (without any mutation, integer is atomic)
|
|
72
|
-
# - result[2] (TIME) (Array<String>) (redis time)
|
|
73
|
-
# - result[3] (ZRANGE) (Array<[String,Float]>) (read locks)
|
|
59
|
+
# NOTE: (pipeline layout) the replies of the pipeline commands (`pipelined` always returns
|
|
60
|
+
# an array of the replies):
|
|
61
|
+
# - result[0] (HGETALL) (Hash<String,String>)
|
|
62
|
+
# => (will be mutated further with different value types)
|
|
63
|
+
# - result[1] (PTTL) (Integer)
|
|
64
|
+
# => (without any mutation, integer is atomic)
|
|
65
|
+
# - result[2] (TIME) (Array<String>) (redis time)
|
|
66
|
+
# - result[3] (ZRANGE) (Array<[String,Float]>) (read locks)
|
|
74
67
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
# rubocop:disable Layout/LineLength
|
|
69
|
+
# @type var result: [Hash[String,String|Float|Integer], Integer, Array[String], Array[[String, Float]]]
|
|
70
|
+
# rubocop:enable Layout/LineLength
|
|
71
|
+
hget_cmd_res = result[0]
|
|
72
|
+
pttl_cmd_res = result[1]
|
|
80
73
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
end
|
|
74
|
+
if hget_cmd_res == {} || pttl_cmd_res == -2 # NOTE: key does not exist
|
|
75
|
+
# NOTE: (RW) there is no write lock => check read locks
|
|
76
|
+
read_lock_info(redis_client, lock_name, lock_key, result[2], result[3])
|
|
77
|
+
else
|
|
78
|
+
hget_cmd_res.tap do |lock_data|
|
|
79
|
+
lock_data['lock_key'] = lock_key
|
|
80
|
+
lock_data['rw_mode'] = 'write'
|
|
81
|
+
lock_data['ts'] = Float(lock_data['ts'])
|
|
82
|
+
lock_data['ini_ttl'] = Integer(lock_data['ini_ttl'])
|
|
83
|
+
lock_data['rem_ttl'] = ((pttl_cmd_res == -1) ? Float::INFINITY : pttl_cmd_res)
|
|
84
|
+
lock_data['spc_cnt'] = Integer(lock_data['spc_cnt']) if lock_data['spc_cnt']
|
|
85
|
+
lock_data['l_spc_ts'] = Float(lock_data['l_spc_ts']) if lock_data['l_spc_ts']
|
|
86
|
+
lock_data['spc_ext_ttl'] = Integer(lock_data['spc_ext_ttl']) if lock_data['spc_ext_ttl']
|
|
87
|
+
lock_data['l_spc_ext_ini_ttl'] =
|
|
88
|
+
Integer(lock_data['l_spc_ext_ini_ttl']) if lock_data.key?('l_spc_ext_ini_ttl')
|
|
89
|
+
lock_data['l_spc_ext_ts'] =
|
|
90
|
+
Float(lock_data['l_spc_ext_ts']) if lock_data['l_spc_ext_ts']
|
|
99
91
|
end
|
|
100
92
|
end
|
|
101
93
|
end
|
|
@@ -3,18 +3,21 @@
|
|
|
3
3
|
# NOTE: Lock Series PoC
|
|
4
4
|
# @api private
|
|
5
5
|
# @since 1.16.1
|
|
6
|
+
# @version 1.22.0
|
|
6
7
|
module RedisQueuedLocks::Acquirer::LockSeriesPoC::InstrVisitor # steep:ignore
|
|
7
8
|
class << self
|
|
8
9
|
# NOTE: Lock Series PoC
|
|
9
10
|
# @param rw_mode [Symbol] The mode of the lock series (`:read` or `:write`).
|
|
11
|
+
# @param priority [Integer] The lock request priority of the series.
|
|
10
12
|
# @api private
|
|
11
13
|
# @since 1.16.1
|
|
12
|
-
# @version 1.
|
|
14
|
+
# @version 1.22.0
|
|
13
15
|
def lock_series_obtained( # steep:ignore
|
|
14
16
|
instrumenter,
|
|
15
17
|
instr_sampled,
|
|
16
18
|
lock_keys,
|
|
17
19
|
rw_mode,
|
|
20
|
+
priority,
|
|
18
21
|
ttl,
|
|
19
22
|
acq_id,
|
|
20
23
|
hst_id,
|
|
@@ -24,20 +27,22 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::InstrVisitor # steep:ignore
|
|
|
24
27
|
)
|
|
25
28
|
return unless instr_sampled
|
|
26
29
|
instrumenter.notify('redis_queued_locks.lock_series_obtained', {
|
|
27
|
-
lock_keys:, rw_mode:, ttl:, acq_id:, hst_id:, ts:, acq_time:, instrument:
|
|
30
|
+
lock_keys:, rw_mode:, priority:, ttl:, acq_id:, hst_id:, ts:, acq_time:, instrument:
|
|
28
31
|
}) rescue nil
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
# NOTE: Lock Series PoC
|
|
32
35
|
# @param rw_mode [Symbol] The mode of the lock series (`:read` or `:write`).
|
|
36
|
+
# @param priority [Integer] The lock request priority of the series.
|
|
33
37
|
# @api private
|
|
34
38
|
# @since 1.16.1
|
|
35
|
-
# @version 1.
|
|
39
|
+
# @version 1.22.0
|
|
36
40
|
def lock_series_hold_and_release( # steep:ignore
|
|
37
41
|
instrumenter,
|
|
38
42
|
instr_sampled,
|
|
39
43
|
lock_keys,
|
|
40
44
|
rw_mode,
|
|
45
|
+
priority,
|
|
41
46
|
ttl,
|
|
42
47
|
acq_id,
|
|
43
48
|
hst_id,
|
|
@@ -48,8 +53,9 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::InstrVisitor # steep:ignore
|
|
|
48
53
|
)
|
|
49
54
|
return unless instr_sampled
|
|
50
55
|
instrumenter.notify('redis_queued_locks.lock_series_hold_and_release', {
|
|
51
|
-
lock_keys:, rw_mode:, hold_time:, ttl:, acq_id:, hst_id:, ts:, acq_time:,
|
|
52
|
-
|
|
56
|
+
lock_keys:, rw_mode:, priority:, hold_time:, ttl:, acq_id:, hst_id:, ts:, acq_time:,
|
|
57
|
+
instrument:
|
|
58
|
+
}) rescue nil
|
|
53
59
|
end
|
|
54
60
|
end
|
|
55
61
|
end
|
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
# NOTE: Lock Series PoC
|
|
4
4
|
# @api private
|
|
5
5
|
# @since 1.16.1
|
|
6
|
+
# @version 1.22.0
|
|
6
7
|
module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
7
8
|
class << self
|
|
8
9
|
# NOTE: Lock Series PoC
|
|
9
10
|
# @param rw_mode [Symbol] The mode of the lock series (`:read` or `:write`).
|
|
11
|
+
# @param priority [Integer] The lock request priority of the series.
|
|
10
12
|
# @api private
|
|
11
13
|
# @since 1.16.0
|
|
12
|
-
# @version 1.
|
|
14
|
+
# @version 1.22.0
|
|
13
15
|
def start_lock_series_obtaining( # steep:ignore
|
|
14
16
|
logger,
|
|
15
17
|
log_sampled,
|
|
@@ -18,7 +20,8 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
|
18
20
|
acquirer_id,
|
|
19
21
|
host_id,
|
|
20
22
|
access_strategy,
|
|
21
|
-
rw_mode
|
|
23
|
+
rw_mode,
|
|
24
|
+
priority
|
|
22
25
|
)
|
|
23
26
|
return unless log_sampled
|
|
24
27
|
|
|
@@ -29,15 +32,17 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
|
29
32
|
"acq_id => '#{acquirer_id}' " \
|
|
30
33
|
"hst_id => '#{host_id}' " \
|
|
31
34
|
"acs_strat => '#{access_strategy}' " \
|
|
32
|
-
"rw_mode => '#{rw_mode}'"
|
|
33
|
-
|
|
35
|
+
"rw_mode => '#{rw_mode}' " \
|
|
36
|
+
"priority => #{priority}"
|
|
37
|
+
end rescue nil
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
# NOTE: Lock Series PoC
|
|
37
41
|
# @param rw_mode [Symbol] The mode of the lock series (`:read` or `:write`).
|
|
42
|
+
# @param priority [Integer] The lock request priority of the series.
|
|
38
43
|
# @api private
|
|
39
44
|
# @since 1.16.0
|
|
40
|
-
# @version 1.
|
|
45
|
+
# @version 1.22.0
|
|
41
46
|
def lock_series_obtained( # steep:ignore
|
|
42
47
|
logger,
|
|
43
48
|
log_sampled,
|
|
@@ -47,7 +52,8 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
|
47
52
|
host_id,
|
|
48
53
|
acq_time,
|
|
49
54
|
access_strategy,
|
|
50
|
-
rw_mode
|
|
55
|
+
rw_mode,
|
|
56
|
+
priority
|
|
51
57
|
)
|
|
52
58
|
return unless log_sampled
|
|
53
59
|
|
|
@@ -59,15 +65,17 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
|
59
65
|
"hst_id => '#{host_id}' " \
|
|
60
66
|
"acs_strat => '#{access_strategy}' " \
|
|
61
67
|
"rw_mode => '#{rw_mode}' " \
|
|
68
|
+
"priority => #{priority} " \
|
|
62
69
|
"acq_time => #{acq_time} (ms)"
|
|
63
|
-
end
|
|
70
|
+
end rescue nil
|
|
64
71
|
end
|
|
65
72
|
|
|
66
73
|
# NOTE: Lock Series PoC
|
|
67
74
|
# @param rw_mode [Symbol] The mode of the lock series (`:read` or `:write`).
|
|
75
|
+
# @param priority [Integer] The lock request priority of the series.
|
|
68
76
|
# @api private
|
|
69
77
|
# @since 1.16.0
|
|
70
|
-
# @version 1.
|
|
78
|
+
# @version 1.22.0
|
|
71
79
|
def expire_lock_series( # steep:ignore
|
|
72
80
|
logger,
|
|
73
81
|
log_sampled,
|
|
@@ -76,7 +84,8 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
|
76
84
|
acquirer_id,
|
|
77
85
|
host_id,
|
|
78
86
|
access_strategy,
|
|
79
|
-
rw_mode
|
|
87
|
+
rw_mode,
|
|
88
|
+
priority
|
|
80
89
|
)
|
|
81
90
|
return unless log_sampled
|
|
82
91
|
|
|
@@ -87,7 +96,8 @@ module RedisQueuedLocks::Acquirer::LockSeriesPoC::LogVisitor # steep:ignore
|
|
|
87
96
|
"acq_id => '#{acquirer_id}' " \
|
|
88
97
|
"hst_id => '#{host_id}' " \
|
|
89
98
|
"acs_strat => '#{access_strategy}' " \
|
|
90
|
-
"rw_mode => '#{rw_mode}'"
|
|
99
|
+
"rw_mode => '#{rw_mode}' " \
|
|
100
|
+
"priority => #{priority}"
|
|
91
101
|
end rescue nil
|
|
92
102
|
end
|
|
93
103
|
end
|