redis_queued_locks 0.0.8 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -0
- data/README.md +26 -17
- data/lib/redis_queued_locks/acquier.rb +31 -3
- data/lib/redis_queued_locks/client.rb +34 -23
- data/lib/redis_queued_locks/resource.rb +33 -2
- data/lib/redis_queued_locks/version.rb +2 -2
- data/lib/redis_queued_locks.rb +1 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 28714dd149659f7c58634868219b3e020df6304253db120fda241304a82ce781
|
4
|
+
data.tar.gz: 52e9193aa4945598f7da31d202cfc445f2b5b63009f5f09e260a732b02e3ac64
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b0f02df991559f21667288ebf690695909d65766cb2c9dd809d18d62a34e722d35d898e227ef38cf12d5acf96d271b7c0a078b1aa8ce47b93645fdd27b36d043
|
7
|
+
data.tar.gz: 5f60948e47cebdc9ff2de6a594aa68155c39ee262fd0662afbe293b672ce811c74a5182f8793be7d3860a8361560213108f25fd00d8a1891cd72a353d3103b25
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.0.10] - 2024-02-27
|
4
|
+
### Changed
|
5
|
+
- Minor documentation updates;
|
6
|
+
|
7
|
+
## [0.0.9] - 2024-02-27
|
8
|
+
### Changed
|
9
|
+
- The lock acquier identifier (`acq_id`) now includes the fiber id, the ractor id and an unique per-process
|
10
|
+
10 byte string. It is added in order to prevent collisions between different processes/pods
|
11
|
+
that will have the same procjet id / thread id identifiers (cuz it is an object_id integers) that can lead
|
12
|
+
to the same position with the same `acq_id` for different processes/pods in the lock request queue.
|
13
|
+
|
3
14
|
## [0.0.8] - 2024-02-27
|
4
15
|
### Added
|
5
16
|
- `RedisQueuedLock::Client#locked?`
|
data/README.md
CHANGED
@@ -60,7 +60,7 @@ require 'redis_queued_locks'
|
|
60
60
|
require 'redis_queued_locks'
|
61
61
|
|
62
62
|
# Step 1: initialize RedisClient instance
|
63
|
-
|
63
|
+
redis_client = RedisClient.config.new_pool # NOTE: provide your own RedisClient instance
|
64
64
|
|
65
65
|
# Step 2: initialize RedisQueuedLock::Client instance
|
66
66
|
rq_lock_client = RedisQueuedLocks::Client.new(redis_client) do |config|
|
@@ -119,6 +119,14 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
|
|
119
119
|
# - payload: <hash> requried;
|
120
120
|
# - disabled by default via VoidNotifier;
|
121
121
|
config.instrumenter = RedisQueuedLocks::Instrument::ActiveSupport
|
122
|
+
|
123
|
+
# (default: -> { RedisQueuedLocks::Resource.calc_uniq_identity })
|
124
|
+
# - uniqude idenfitier that is uniq per process/pod;
|
125
|
+
# - prevents potential lock-acquirement collisions bettween different process/pods
|
126
|
+
# that have identical process_id/thread_id/fiber_id/ractor_id (identivcal acquier ids);
|
127
|
+
# - it is calculated once per `RedisQueudLocks::Client` instance;
|
128
|
+
# - expects the proc object;
|
129
|
+
config.uniq_identifier = -> { RedisQueuedLocks::Resource.calc_uniq_identity }
|
122
130
|
end
|
123
131
|
```
|
124
132
|
|
@@ -142,8 +150,6 @@ end
|
|
142
150
|
```ruby
|
143
151
|
def lock(
|
144
152
|
lock_name,
|
145
|
-
process_id: RedisQueuedLocks::Resource.get_process_id,
|
146
|
-
thread_id: RedisQueuedLocks::Resource.get_thread_id,
|
147
153
|
ttl: config[:default_lock_ttl],
|
148
154
|
queue_ttl: config[:default_queue_ttl],
|
149
155
|
timeout: config[:try_to_lock_timeout],
|
@@ -151,16 +157,13 @@ def lock(
|
|
151
157
|
retry_delay: config[:retry_delay],
|
152
158
|
retry_jitter: config[:retry_jitter],
|
153
159
|
raise_errors: false,
|
160
|
+
identity: uniq_identity, # (attr_accessor) calculated during client instantiation via config[:uniq_identifier] proc;
|
154
161
|
&block
|
155
162
|
)
|
156
163
|
```
|
157
164
|
|
158
165
|
- `lock_name` - `[String]`
|
159
166
|
- Lock name to be obtained.
|
160
|
-
- `process_id` - `[Integer,String]`
|
161
|
-
- The process that want to acquire the lock.
|
162
|
-
- `thread_id` - `[Integer,String]`
|
163
|
-
- The process's thread that want to acquire the lock.
|
164
167
|
- `ttl` [Integer]
|
165
168
|
- Lock's time to live (in milliseconds).
|
166
169
|
- `queue_ttl` - `[Integer]`
|
@@ -177,6 +180,12 @@ def lock(
|
|
177
180
|
- See RedisQueuedLocks::Instrument::ActiveSupport for example.
|
178
181
|
- `raise_errors` - `[Boolean]`
|
179
182
|
- Raise errors on library-related limits such as timeout or retry count limit.
|
183
|
+
- `identity` - `[String]`
|
184
|
+
- An unique string that is unique per `RedisQueuedLock::Client` instance. Resolves the
|
185
|
+
collisions between the same process_id/thread_id/fiber_id/ractor_id identifiers on different
|
186
|
+
pods or/and nodes of your application;
|
187
|
+
- It is calculated once during `RedisQueuedLock::Client` instantiation and stored in `@uniq_identity`
|
188
|
+
ivar (accessed via `uniq_dentity` accessor method);
|
180
189
|
- `block` - `[Block]`
|
181
190
|
- A block of code that should be executed after the successfully acquired lock.
|
182
191
|
- If block is **passed** the obtained lock will be released after the block execution or it's ttl (what will happen first);
|
@@ -190,7 +199,7 @@ Return value:
|
|
190
199
|
ok: true,
|
191
200
|
result: {
|
192
201
|
lock_key: String, # acquierd lock key ("rql:lock:your_lock_name")
|
193
|
-
acq_id: String, # acquier identifier ("
|
202
|
+
acq_id: String, # acquier identifier ("process_id/thread_id/fiber_id/ractor_id/identity")
|
194
203
|
ts: Integer, # time (epoch) when lock was obtained (integer)
|
195
204
|
ttl: Integer # lock's time to live in milliseconds (integer)
|
196
205
|
}
|
@@ -214,14 +223,13 @@ Return value:
|
|
214
223
|
```ruby
|
215
224
|
def lock!(
|
216
225
|
lock_name,
|
217
|
-
process_id: RedisQueuedLocks::Resource.get_process_id,
|
218
|
-
thread_id: RedisQueuedLocks::Resource.get_thread_id,
|
219
226
|
ttl: config[:default_lock_ttl],
|
220
227
|
queue_ttl: config[:default_queue_ttl],
|
221
228
|
timeout: config[:default_timeout],
|
222
229
|
retry_count: config[:retry_count],
|
223
230
|
retry_delay: config[:retry_delay],
|
224
231
|
retry_jitter: config[:retry_jitter],
|
232
|
+
identity: uniq_identity,
|
225
233
|
&block
|
226
234
|
)
|
227
235
|
```
|
@@ -236,7 +244,7 @@ See `#lock` method [documentation](#lock---obtain-a-lock).
|
|
236
244
|
- returns `nil` if lock does not exist;
|
237
245
|
- lock data (`Hash<Symbol,String|Integer>`):
|
238
246
|
- `lock_key` - `string` - lock key in redis;
|
239
|
-
- `acq_id` - `string` - acquier identifier (process_id/thread_id
|
247
|
+
- `acq_id` - `string` - acquier identifier (process_id/thread_id/fiber_id/ractor_id/identity);
|
240
248
|
- `ts` - `integer`/`epoch` - the time lock was obtained;
|
241
249
|
- `init_ttl` - `integer` - (milliseconds) initial lock key ttl;
|
242
250
|
- `rem_ttl` - `integer` - (milliseconds) remaining lock key ttl;
|
@@ -247,7 +255,7 @@ rql.lock_info("your_lock_name")
|
|
247
255
|
# =>
|
248
256
|
{
|
249
257
|
lock_key: "rql:lock:your_lock_name",
|
250
|
-
acq_id: "rql:acq:123/456",
|
258
|
+
acq_id: "rql:acq:123/456/567/678/374dd74324",
|
251
259
|
ts: 123456789,
|
252
260
|
ini_ttl: 123456789,
|
253
261
|
rem_ttl: 123456789
|
@@ -267,7 +275,7 @@ rql.lock_info("your_lock_name")
|
|
267
275
|
- lock queue data (`Hash<Symbol,String|Array<Hash<Symbol,String|Numeric>>`):
|
268
276
|
- `lock_queue` - `string` - lock queue key in redis;
|
269
277
|
- `queue` - `array` - an array of lock requests (array of hashes):
|
270
|
-
- `acq_id` - `string` - acquier identifier (process_id/thread_id by default);
|
278
|
+
- `acq_id` - `string` - acquier identifier (process_id/thread_id/fiber_id/ractor_id/identity by default);
|
271
279
|
- `score` - `float`/`epoch` - time when the lock request was made (epoch);
|
272
280
|
|
273
281
|
```ruby
|
@@ -277,9 +285,9 @@ rql.queue_info("your_lock_name")
|
|
277
285
|
{
|
278
286
|
lock_queue: "rql:lock_queue:your_lock_name",
|
279
287
|
queue: [
|
280
|
-
{ acq_id: "rql:acq:123/456", score: 1},
|
281
|
-
{ acq_id: "rql:acq:123/567", score: 2},
|
282
|
-
{ acq_id: "rql:acq:555/329", score: 3},
|
288
|
+
{ acq_id: "rql:acq:123/456/567/678/fa76df9cc2", score: 1},
|
289
|
+
{ acq_id: "rql:acq:123/567/456/679/c7bfcaf4f9", score: 2},
|
290
|
+
{ acq_id: "rql:acq:555/329/523/127/7329553b11", score: 3},
|
283
291
|
# ...etc
|
284
292
|
]
|
285
293
|
}
|
@@ -422,7 +430,7 @@ Detalized event semantics and payload structure:
|
|
422
430
|
- payload:
|
423
431
|
- `rel_time` - `float`/`milliseconds` - time spent on "realese all locks" operation;
|
424
432
|
- `at` - `integer`/`epoch` - the time when the operation has ended;
|
425
|
-
- `rel_keys` - `integer` - released redis keys count (`released
|
433
|
+
- `rel_keys` - `integer` - released redis keys count (`released queue keys` + `released lock keys`);
|
426
434
|
|
427
435
|
---
|
428
436
|
|
@@ -431,6 +439,7 @@ Detalized event semantics and payload structure:
|
|
431
439
|
- **Major**
|
432
440
|
- Semantic Error objects for unexpected Redis errors;
|
433
441
|
- `100%` test coverage;
|
442
|
+
- sidecar `Ractor` object and `in progress queue` in RedisDB that will extend an acquired lock for long-running blocks of code (that invoked "under" the lock);
|
434
443
|
- **Minor**
|
435
444
|
- `RedisQueuedLocks::Acquier::Try.try_to_lock` - detailed successful result analization;
|
436
445
|
- better code stylization and interesting refactorings;
|
@@ -34,9 +34,13 @@ module RedisQueuedLocks::Acquier
|
|
34
34
|
# @param lock_name [String]
|
35
35
|
# Lock name to be acquier.
|
36
36
|
# @option process_id [Integer,String]
|
37
|
-
# The process that want to acquire
|
37
|
+
# The process that want to acquire a lock.
|
38
38
|
# @option thread_id [Integer,String]
|
39
|
-
# The process's thread that want to acquire
|
39
|
+
# The process's thread that want to acquire a lock.
|
40
|
+
# @option fiber_id [Integer,String]
|
41
|
+
# A current fiber that want to acquire a lock.
|
42
|
+
# @option ractor_id [Integer,String]
|
43
|
+
# The current ractor that want to acquire a lock.
|
40
44
|
# @option ttl [Integer,NilClass]
|
41
45
|
# Lock's time to live (in milliseconds). Nil means "without timeout".
|
42
46
|
# @option queue_ttl [Integer]
|
@@ -53,6 +57,10 @@ module RedisQueuedLocks::Acquier
|
|
53
57
|
# Raise errors on exceptional cases.
|
54
58
|
# @option instrumenter [#notify]
|
55
59
|
# See RedisQueuedLocks::Instrument::ActiveSupport for example.
|
60
|
+
# @option identity [String]
|
61
|
+
# Unique acquire identifier that is also should be unique between processes and pods
|
62
|
+
# on different machines. By default the uniq identity string is
|
63
|
+
# represented as 10 bytes hexstr.
|
56
64
|
# @param [Block]
|
57
65
|
# A block of code that should be executed after the successfully acquired lock.
|
58
66
|
# @return [Hash<Symbol,Any>]
|
@@ -66,6 +74,8 @@ module RedisQueuedLocks::Acquier
|
|
66
74
|
lock_name,
|
67
75
|
process_id:,
|
68
76
|
thread_id:,
|
77
|
+
fiber_id:,
|
78
|
+
ractor_id:,
|
69
79
|
ttl:,
|
70
80
|
queue_ttl:,
|
71
81
|
timeout:,
|
@@ -74,10 +84,17 @@ module RedisQueuedLocks::Acquier
|
|
74
84
|
retry_jitter:,
|
75
85
|
raise_errors:,
|
76
86
|
instrumenter:,
|
87
|
+
identity:,
|
77
88
|
&block
|
78
89
|
)
|
79
90
|
# Step 1: prepare lock requirements (generate lock name, calc lock ttl, etc).
|
80
|
-
acquier_id = RedisQueuedLocks::Resource.acquier_identifier(
|
91
|
+
acquier_id = RedisQueuedLocks::Resource.acquier_identifier(
|
92
|
+
process_id,
|
93
|
+
thread_id,
|
94
|
+
fiber_id,
|
95
|
+
ractor_id,
|
96
|
+
identity
|
97
|
+
)
|
81
98
|
lock_ttl = ttl + REDIS_EXPIRATION_DEVIATION
|
82
99
|
lock_key = RedisQueuedLocks::Resource.prepare_lock_key(lock_name)
|
83
100
|
lock_key_queue = RedisQueuedLocks::Resource.prepare_lock_queue(lock_name)
|
@@ -386,6 +403,17 @@ module RedisQueuedLocks::Acquier
|
|
386
403
|
end
|
387
404
|
end
|
388
405
|
|
406
|
+
# @param redis_client [RedisClient]
|
407
|
+
# @param lock_name [String]
|
408
|
+
# @param milliseconds [Integer]
|
409
|
+
# @return [?]
|
410
|
+
#
|
411
|
+
# @api private
|
412
|
+
# @since 0.1.0
|
413
|
+
def extend_lock_ttl(redis_client, lock_name, milliseconds)
|
414
|
+
|
415
|
+
end
|
416
|
+
|
389
417
|
private
|
390
418
|
|
391
419
|
# @param timeout [NilClass,Integer]
|
@@ -17,6 +17,7 @@ class RedisQueuedLocks::Client
|
|
17
17
|
setting :default_queue_ttl, 15 # NOTE: seconds
|
18
18
|
setting :lock_release_batch_size, 100
|
19
19
|
setting :instrumenter, RedisQueuedLocks::Instrument::VoidNotifier
|
20
|
+
setting :uniq_identifier, -> { RedisQueuedLocks::Resource.calc_uniq_identity }
|
20
21
|
|
21
22
|
# TODO: setting :logger, Logger.new(IO::NULL)
|
22
23
|
# TODO: setting :debug, true/false
|
@@ -30,6 +31,7 @@ class RedisQueuedLocks::Client
|
|
30
31
|
validate('default_queue_ttl', :integer)
|
31
32
|
validate('lock_release_batch_size', :integer)
|
32
33
|
validate('instrumenter') { |val| RedisQueuedLocks::Instrument.valid_interface?(val) }
|
34
|
+
validate('uniq_identifier', :proc)
|
33
35
|
end
|
34
36
|
|
35
37
|
# @return [RedisClient]
|
@@ -38,6 +40,12 @@ class RedisQueuedLocks::Client
|
|
38
40
|
# @since 0.1.0
|
39
41
|
attr_reader :redis_client
|
40
42
|
|
43
|
+
# @return [String]
|
44
|
+
#
|
45
|
+
# @api private
|
46
|
+
# @since 0.1.0
|
47
|
+
attr_accessor :uniq_identity
|
48
|
+
|
41
49
|
# @param redis_client [RedisClient]
|
42
50
|
# Redis connection manager, which will be used for the lock acquierment and distribution.
|
43
51
|
# It should be an instance of RedisClient.
|
@@ -49,15 +57,12 @@ class RedisQueuedLocks::Client
|
|
49
57
|
# @since 0.1.0
|
50
58
|
def initialize(redis_client, &configs)
|
51
59
|
configure(&configs)
|
60
|
+
@uniq_identity = config[:uniq_identifier].call
|
52
61
|
@redis_client = redis_client
|
53
62
|
end
|
54
63
|
|
55
64
|
# @param lock_name [String]
|
56
65
|
# Lock name to be obtained.
|
57
|
-
# @option process_id [Integer,String]
|
58
|
-
# The process that want to acquire the lock.
|
59
|
-
# @option thread_id [Integer,String]
|
60
|
-
# The process's thread that want to acquire the lock.
|
61
66
|
# @option ttl [Integer]
|
62
67
|
# Lock's time to live (in milliseconds).
|
63
68
|
# @option queue_ttl [Integer]
|
@@ -74,17 +79,19 @@ class RedisQueuedLocks::Client
|
|
74
79
|
# See RedisQueuedLocks::Instrument::ActiveSupport for example.
|
75
80
|
# @option raise_errors [Boolean]
|
76
81
|
# Raise errors on library-related limits such as timeout or failed lock obtain.
|
82
|
+
# @option identity [String]
|
83
|
+
# Unique acquire identifier that is also should be unique between processes and pods
|
84
|
+
# on different machines. By default the uniq identity string is
|
85
|
+
# represented as 10 bytes hexstr.
|
77
86
|
# @param block [Block]
|
78
87
|
# A block of code that should be executed after the successfully acquired lock.
|
79
|
-
# @return [Hash<Symbol,Any
|
88
|
+
# @return [Hash<Symbol,Any>,yield]
|
80
89
|
# Format: { ok: true/false, result: Symbol/Hash }.
|
81
90
|
#
|
82
91
|
# @api public
|
83
92
|
# @since 0.1.0
|
84
93
|
def lock(
|
85
94
|
lock_name,
|
86
|
-
process_id: RedisQueuedLocks::Resource.get_process_id,
|
87
|
-
thread_id: RedisQueuedLocks::Resource.get_thread_id,
|
88
95
|
ttl: config[:default_lock_ttl],
|
89
96
|
queue_ttl: config[:default_queue_ttl],
|
90
97
|
timeout: config[:try_to_lock_timeout],
|
@@ -92,13 +99,16 @@ class RedisQueuedLocks::Client
|
|
92
99
|
retry_delay: config[:retry_delay],
|
93
100
|
retry_jitter: config[:retry_jitter],
|
94
101
|
raise_errors: false,
|
102
|
+
identity: uniq_identity,
|
95
103
|
&block
|
96
104
|
)
|
97
105
|
RedisQueuedLocks::Acquier.acquire_lock!(
|
98
106
|
redis_client,
|
99
107
|
lock_name,
|
100
|
-
process_id
|
101
|
-
thread_id
|
108
|
+
process_id: RedisQueuedLocks::Resource.get_process_id,
|
109
|
+
thread_id: RedisQueuedLocks::Resource.get_thread_id,
|
110
|
+
fiber_id: RedisQueuedLocks::Resource.get_fiber_id,
|
111
|
+
ractor_id: RedisQueuedLocks::Resource.get_ractor_id,
|
102
112
|
ttl:,
|
103
113
|
queue_ttl:,
|
104
114
|
timeout:,
|
@@ -107,6 +117,7 @@ class RedisQueuedLocks::Client
|
|
107
117
|
retry_jitter:,
|
108
118
|
raise_errors:,
|
109
119
|
instrumenter: config[:instrumenter],
|
120
|
+
identity:,
|
110
121
|
&block
|
111
122
|
)
|
112
123
|
end
|
@@ -117,20 +128,17 @@ class RedisQueuedLocks::Client
|
|
117
128
|
# @since 0.1.0
|
118
129
|
def lock!(
|
119
130
|
lock_name,
|
120
|
-
process_id: RedisQueuedLocks::Resource.get_process_id,
|
121
|
-
thread_id: RedisQueuedLocks::Resource.get_thread_id,
|
122
131
|
ttl: config[:default_lock_ttl],
|
123
132
|
queue_ttl: config[:default_queue_ttl],
|
124
133
|
timeout: config[:default_timeout],
|
125
134
|
retry_count: config[:retry_count],
|
126
135
|
retry_delay: config[:retry_delay],
|
127
136
|
retry_jitter: config[:retry_jitter],
|
137
|
+
identity: uniq_identity,
|
128
138
|
&block
|
129
139
|
)
|
130
140
|
lock(
|
131
141
|
lock_name,
|
132
|
-
process_id:,
|
133
|
-
thread_id:,
|
134
142
|
ttl:,
|
135
143
|
queue_ttl:,
|
136
144
|
timeout:,
|
@@ -138,6 +146,7 @@ class RedisQueuedLocks::Client
|
|
138
146
|
retry_delay:,
|
139
147
|
retry_jitter:,
|
140
148
|
raise_errors: true,
|
149
|
+
identity:,
|
141
150
|
&block
|
142
151
|
)
|
143
152
|
end
|
@@ -148,11 +157,7 @@ class RedisQueuedLocks::Client
|
|
148
157
|
# @api public
|
149
158
|
# @since 0.1.0
|
150
159
|
def unlock(lock_name)
|
151
|
-
RedisQueuedLocks::Acquier.release_lock!(
|
152
|
-
redis_client,
|
153
|
-
lock_name,
|
154
|
-
config[:instrumenter]
|
155
|
-
)
|
160
|
+
RedisQueuedLocks::Acquier.release_lock!(redis_client, lock_name, config[:instrumenter])
|
156
161
|
end
|
157
162
|
|
158
163
|
# @param lock_name [String]
|
@@ -191,17 +196,23 @@ class RedisQueuedLocks::Client
|
|
191
196
|
RedisQueuedLocks::Acquier.queue_info(redis_client, lock_name)
|
192
197
|
end
|
193
198
|
|
199
|
+
# @param lock_name [String]
|
200
|
+
# @param milliseconds [Integer] How many milliseconds should be added.
|
201
|
+
# @return [?]
|
202
|
+
#
|
203
|
+
# @api public
|
204
|
+
# @since 0.1.0
|
205
|
+
def extend_lock_ttl(lock_name, milliseconds)
|
206
|
+
RedisQueuedLocks::Acquier.extend_lock_ttl(redis_client, lock_name)
|
207
|
+
end
|
208
|
+
|
194
209
|
# @option batch_size [Integer]
|
195
210
|
# @return [Hash<Symbol,Any>] Format: { ok: true/false, result: Symbol/Hash }.
|
196
211
|
#
|
197
212
|
# @api public
|
198
213
|
# @since 0.1.0
|
199
214
|
def clear_locks(batch_size: config[:lock_release_batch_size])
|
200
|
-
RedisQueuedLocks::Acquier.release_all_locks!(
|
201
|
-
redis_client,
|
202
|
-
batch_size,
|
203
|
-
config[:instrumenter]
|
204
|
-
)
|
215
|
+
RedisQueuedLocks::Acquier.release_all_locks!(redis_client, batch_size, config[:instrumenter])
|
205
216
|
end
|
206
217
|
end
|
207
218
|
# rubocop:enable Metrics/ClassLength
|
@@ -16,14 +16,29 @@ module RedisQueuedLocks::Resource
|
|
16
16
|
LOCK_QUEUE_PATTERN = 'rql:lock_queue:*'
|
17
17
|
|
18
18
|
class << self
|
19
|
+
# Returns 10-byte unique identifier. It is used for uniquely
|
20
|
+
# identify current process between different nodes/pods of your application
|
21
|
+
# during the lock obtaining and self-identifying in the lock queue.
|
22
|
+
#
|
23
|
+
# @return [String]
|
24
|
+
#
|
25
|
+
# @api private
|
26
|
+
# @since 0.1.0
|
27
|
+
def calc_uniq_identity
|
28
|
+
SecureRandom.hex(5)
|
29
|
+
end
|
30
|
+
|
19
31
|
# @param process_id [Integer,String]
|
20
32
|
# @param thread_id [Integer,String]
|
33
|
+
# @param fiber_id [Integer,String]
|
34
|
+
# @param ractor_id [Integer,String]
|
35
|
+
# @param identity [String]
|
21
36
|
# @return [String]
|
22
37
|
#
|
23
38
|
# @api private
|
24
39
|
# @since 0.1.0
|
25
|
-
def acquier_identifier(process_id
|
26
|
-
"rql:acq:#{process_id}/#{thread_id}"
|
40
|
+
def acquier_identifier(process_id, thread_id, fiber_id, ractor_id, identity)
|
41
|
+
"rql:acq:#{process_id}/#{thread_id}/#{fiber_id}/#{ractor_id}/#{identity}"
|
27
42
|
end
|
28
43
|
|
29
44
|
# @param lock_name [String]
|
@@ -79,6 +94,22 @@ module RedisQueuedLocks::Resource
|
|
79
94
|
::Thread.current.object_id
|
80
95
|
end
|
81
96
|
|
97
|
+
# @return [Integer]
|
98
|
+
#
|
99
|
+
# @api private
|
100
|
+
# @since 0.1.0
|
101
|
+
def get_fiber_id
|
102
|
+
::Fiber.current.object_id
|
103
|
+
end
|
104
|
+
|
105
|
+
# @return [Integer]
|
106
|
+
#
|
107
|
+
# @api private
|
108
|
+
# @since 0.1.0
|
109
|
+
def get_ractor_id
|
110
|
+
::Ractor.current.object_id
|
111
|
+
end
|
112
|
+
|
82
113
|
# @return [Integer]
|
83
114
|
#
|
84
115
|
# @api private
|
data/lib/redis_queued_locks.rb
CHANGED