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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/project-overview.md +249 -36
  3. data/.claude/rules/acquirer.md +16 -14
  4. data/.claude/rules/arguments.md +2 -2
  5. data/.claude/rules/changelog.md +27 -0
  6. data/.claude/rules/git.md +1 -1
  7. data/.claude/rules/logic.md +34 -13
  8. data/.claude/rules/swarm.md +4 -5
  9. data/.claude/rules/tests.md +9 -6
  10. data/.claude/rules/type-checking.md +13 -14
  11. data/.claude/rules/visitors.md +13 -14
  12. data/.claude/skills/rql-code-review/SKILL.md +134 -43
  13. data/CHANGELOG.md +105 -125
  14. data/CLAUDE.md +11 -9
  15. data/README.md +501 -136
  16. data/Rakefile +11 -0
  17. data/lib/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rb +1 -0
  18. data/lib/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rb +68 -10
  19. data/lib/redis_queued_locks/acquirer/acquire_lock/log_visitor.rb +82 -15
  20. data/lib/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rb +92 -14
  21. data/lib/redis_queued_locks/acquirer/acquire_lock/try_to_lock.rb +441 -63
  22. data/lib/redis_queued_locks/acquirer/acquire_lock/with_acq_timeout.rb +2 -2
  23. data/lib/redis_queued_locks/acquirer/acquire_lock/yield_expire/log_visitor.rb +1 -0
  24. data/lib/redis_queued_locks/acquirer/acquire_lock/yield_expire.rb +5 -5
  25. data/lib/redis_queued_locks/acquirer/acquire_lock.rb +176 -39
  26. data/lib/redis_queued_locks/acquirer/clear_dead_requests.rb +322 -49
  27. data/lib/redis_queued_locks/acquirer/extend_lock_ttl.rb +125 -13
  28. data/lib/redis_queued_locks/acquirer/is_locked.rb +0 -1
  29. data/lib/redis_queued_locks/acquirer/is_queued.rb +0 -1
  30. data/lib/redis_queued_locks/acquirer/keys.rb +16 -3
  31. data/lib/redis_queued_locks/acquirer/lock_info.rb +31 -39
  32. data/lib/redis_queued_locks/acquirer/lock_series_poc/instr_visitor.rb +11 -5
  33. data/lib/redis_queued_locks/acquirer/lock_series_poc/log_visitor.rb +20 -10
  34. data/lib/redis_queued_locks/acquirer/lock_series_poc.rb +105 -36
  35. data/lib/redis_queued_locks/acquirer/locks.rb +32 -11
  36. data/lib/redis_queued_locks/acquirer/queue_info.rb +30 -8
  37. data/lib/redis_queued_locks/acquirer/queues.rb +26 -6
  38. data/lib/redis_queued_locks/acquirer/reindex_locks.rb +117 -4
  39. data/lib/redis_queued_locks/acquirer/release_all_locks.rb +37 -6
  40. data/lib/redis_queued_locks/acquirer/release_lock.rb +33 -7
  41. data/lib/redis_queued_locks/acquirer/release_locks_of.rb +45 -6
  42. data/lib/redis_queued_locks/acquirer/release_read_lock.rb +22 -3
  43. data/lib/redis_queued_locks/client.rb +140 -56
  44. data/lib/redis_queued_locks/config.rb +105 -14
  45. data/lib/redis_queued_locks/errors.rb +34 -4
  46. data/lib/redis_queued_locks/instrument/sampler.rb +4 -7
  47. data/lib/redis_queued_locks/logging/sampler.rb +4 -8
  48. data/lib/redis_queued_locks/resource.rb +137 -12
  49. data/lib/redis_queued_locks/swarm/flush_zombies.rb +1 -0
  50. data/lib/redis_queued_locks/swarm/redis_client_builder.rb +8 -4
  51. data/lib/redis_queued_locks/swarm/swarm_element/threaded.rb +8 -6
  52. data/lib/redis_queued_locks/swarm/zombie_info.rb +6 -2
  53. data/lib/redis_queued_locks/swarm.rb +86 -5
  54. data/lib/redis_queued_locks/utilities.rb +1 -1
  55. data/lib/redis_queued_locks/version.rb +2 -2
  56. data/rbs_collection.lock.yaml +4 -0
  57. data/rbs_collection.yaml +2 -1
  58. data/sig/manifest.yml +1 -0
  59. data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue/log_visitor.rbs +2 -2
  60. data/sig/redis_queued_locks/acquirer/acquire_lock/dequeue_from_lock_queue.rbs +2 -2
  61. data/sig/redis_queued_locks/acquirer/acquire_lock/instr_visitor.rbs +25 -5
  62. data/sig/redis_queued_locks/acquirer/acquire_lock/log_visitor.rbs +32 -12
  63. data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock/log_visitor.rbs +61 -40
  64. data/sig/redis_queued_locks/acquirer/acquire_lock/try_to_lock.rbs +59 -11
  65. data/sig/redis_queued_locks/acquirer/acquire_lock/{yield_with_expire → yield_expire}/log_visitor.rbs +4 -4
  66. data/sig/redis_queued_locks/acquirer/acquire_lock/yield_expire.rbs +4 -4
  67. data/sig/redis_queued_locks/acquirer/acquire_lock.rbs +6 -4
  68. data/sig/redis_queued_locks/acquirer/clear_dead_requests.rbs +23 -1
  69. data/sig/redis_queued_locks/acquirer/extend_lock_ttl.rbs +16 -3
  70. data/sig/redis_queued_locks/acquirer/queues.rbs +1 -1
  71. data/sig/redis_queued_locks/acquirer/reindex_locks.rbs +22 -1
  72. data/sig/redis_queued_locks/acquirer/release_lock.rbs +3 -2
  73. data/sig/redis_queued_locks/acquirer/release_read_lock.rbs +1 -1
  74. data/sig/redis_queued_locks/client.rbs +24 -10
  75. data/sig/redis_queued_locks/config.rbs +54 -1
  76. data/sig/redis_queued_locks/errors.rbs +5 -2
  77. data/sig/redis_queued_locks/instrument/sampler.rbs +3 -3
  78. data/sig/redis_queued_locks/instrument/void_notifier.rbs +3 -1
  79. data/sig/redis_queued_locks/logging/sampler.rbs +3 -3
  80. data/sig/redis_queued_locks/resource.rbs +23 -13
  81. data/sig/redis_queued_locks/swarm/swarm_element/threaded.rbs +1 -1
  82. data/sig/redis_queued_locks/utilities.rbs +2 -1
  83. data/sig/redis_queued_locks.rbs +7 -0
  84. data/sig/vendor/redis_client.rbs +1 -0
  85. metadata +4 -3
  86. /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.20.0
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.20.0
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
- if read_write_mode != :read && read_write_mode != :write
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
- if read_write_mode == :read
81
- if all_read_locks != true && all_read_locks != false
82
- raise(
83
- RedisQueuedLocks::ArgumentError,
84
- "`:all_read_locks` argument should be a boolean, got #{all_read_locks.inspect}."
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.20.0
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.20.0
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:
@@ -2,7 +2,6 @@
2
2
 
3
3
  # @api private
4
4
  # @since 1.0.0
5
- # @version 1.18.0
6
5
  module RedisQueuedLocks::Acquirer::IsLocked
7
6
  class << self
8
7
  # @param redis_client [RedisClient]
@@ -2,7 +2,6 @@
2
2
 
3
3
  # @api private
4
4
  # @since 1.0.0
5
- # @version 1.18.0
6
5
  module RedisQueuedLocks::Acquirer::IsQueued
7
6
  class << self
8
7
  # @param redis_client [RedisClient]
@@ -32,8 +32,17 @@ module RedisQueuedLocks::Acquirer::Keys
32
32
  #
33
33
  # @api private
34
34
  # @since 1.0.0
35
- # @version 1.20.0
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 lock_index_score.to_f < lock_index_time
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.20.0
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
- if result == nil
60
- # NOTE:
61
- # - nil result means that during transaction invocation the lock is changed (CAS):
62
- # - lock is expired;
63
- # - lock is released;
64
- # - lock is expired + re-obtained;
65
- nil
66
- else
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
- # rubocop:disable Layout/LineLength
76
- # @type var result: [Hash[String,String|Float|Integer], Integer, Array[String], Array[[String, Float]]]
77
- # rubocop:enable Layout/LineLength
78
- hget_cmd_res = result[0]
79
- pttl_cmd_res = result[1]
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
- if hget_cmd_res == {} || pttl_cmd_res == -2 # NOTE: key does not exist
82
- # NOTE: (RW) there is no write lock => check read locks
83
- read_lock_info(redis_client, lock_name, lock_key, result[2], result[3])
84
- else
85
- hget_cmd_res.tap do |lock_data|
86
- lock_data['lock_key'] = lock_key
87
- lock_data['rw_mode'] = 'write'
88
- lock_data['ts'] = Float(lock_data['ts'])
89
- lock_data['ini_ttl'] = Integer(lock_data['ini_ttl'])
90
- lock_data['rem_ttl'] = ((pttl_cmd_res == -1) ? Float::INFINITY : pttl_cmd_res)
91
- lock_data['spc_cnt'] = Integer(lock_data['spc_cnt']) if lock_data['spc_cnt']
92
- lock_data['l_spc_ts'] = Float(lock_data['l_spc_ts']) if lock_data['l_spc_ts']
93
- lock_data['spc_ext_ttl'] = Integer(lock_data['spc_ext_ttl']) if lock_data['spc_ext_ttl']
94
- lock_data['l_spc_ext_ini_ttl'] =
95
- Integer(lock_data['l_spc_ext_ini_ttl']) if lock_data.key?('l_spc_ext_ini_ttl')
96
- lock_data['l_spc_ext_ts'] =
97
- Float(lock_data['l_spc_ext_ts']) if lock_data['l_spc_ext_ts']
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.18.0
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.18.0
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:, instrument:
52
- }) # rescue nil
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.18.0
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
- end # rescue nil
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.18.0
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 # rescue nil
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.18.0
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