redis_queued_locks 0.0.16 → 0.0.17

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 524740cce42224df4610bce35ced68e38f0fceb13ba233fe9c2f4ceac76fa49a
4
- data.tar.gz: f3cb8b791292ba1c98b9b97c2a23b413edf74a3a5a25cebba5c7e3900f5705fd
3
+ metadata.gz: eb745a97296f4661f7a68d7719d7bdb894521348d6aa25b92b23b4fcffce56cd
4
+ data.tar.gz: e12566b1c653ad97bf973887d4511482c628d8ec27fd265901d1d4bfba9c112b
5
5
  SHA512:
6
- metadata.gz: 732ffd5fe549d093f8bc4ef6edd1db9751aa951b0cd0f75d3ba63b8facc7a5bea1d31c88527ae2ae1c3bd4bfc5e686a447ab3907d18f37c1756167d306c929aa
7
- data.tar.gz: f6b95308ec0653068de4816ce47a45f2470000079d468a54950f4a4bfc10c2689778108a265d3be097811d0da31b16678d14aa284903066e9c889201cc412abb
6
+ metadata.gz: c3e6f4c421c8e6fb9b3933c01ebcd23d5762f0bdb0581333e2d85ab478a8002d8bce360bfabaab29d819c92a4f148e6562d0fa426e5999b0fc2d1c9b59f3eaa7
7
+ data.tar.gz: 42a5800757191ea80797c7462b765c5dd4187771ce73c6c9af70f6653dea5599710d8569b5a2fc1a0c30cb0b3483abfac557bd888a7f4bcbde4ac4a7de308021
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.17] - 2024-02-29
4
+ ### Added
5
+ - `RedisQueuedLocks::Client#locks` - list of obtained locks;
6
+ - `RedisQueuedLocks::Client#queues` - list of existing lock request queus;
7
+ - `RedisQueuedLocks::Client#keys` - get list of taken locks and queues;
8
+
3
9
  ## [0.0.16] - 2024-02-29
4
10
  ### Fixed
5
11
  - Execution delay formula returns the value "in seconds" (should be "in milliseconds");
data/README.md CHANGED
@@ -21,6 +21,10 @@ Each lock request is put into the request queue and processed in order of their
21
21
  - [queued?](#queued)
22
22
  - [unlock](#unlock---release-a-lock)
23
23
  - [clear_locks](#clear_locks---release-all-locks-and-lock-queues)
24
+ - [extend_lock_ttl](#extend_lock_ttl)
25
+ - [locks](#locks---get-list-of-obtained-locks)
26
+ - [queues](#queues---get-list-of-lock-request-queues)
27
+ - [keys](#keys---get-list-of-taken-locks-and-queues)
24
28
  - [Instrumentation](#instrumentation)
25
29
  - [Instrumentation Events](#instrumentation-events)
26
30
  - [Roadmap](#roadmap)
@@ -104,10 +108,15 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
104
108
  config.default_queue_ttl = 15
105
109
 
106
110
  # (default: 100)
107
- # - how many items will be released at a time in RedisQueuedLocks::Client#clear_locks logic;
108
- # - affects the performancs capabilites (redis, rubyvm);
111
+ # - how many items will be released at a time in RedisQueuedLocks::Client#clear_locks logic (uses SCAN);
112
+ # - affects the performancs of your Redis and Ruby Application (configure thoughtfully);
109
113
  config.lock_release_batch_size = 100
110
114
 
115
+ # (default: 500)
116
+ # - how many items should be extracted from redis during the #locks, #queues and #keys operations (uses SCAN);
117
+ # - affects the performance of your Redis and Ruby Application (configure thoughtfully;)
118
+ config.key_extraction_batch_size = 500
119
+
111
120
  # (default: RedisQueuedLocks::Instrument::VoidNotifier)
112
121
  # - instrumentation layer;
113
122
  # - you can provde your own instrumenter with `#notify(event, payload = {})`
@@ -138,6 +147,10 @@ end
138
147
  - [queued?](#queued)
139
148
  - [unlock](#unlock---release-a-lock)
140
149
  - [clear_locks](#clear_locks---release-all-locks-and-lock-queues)
150
+ - [extend_lock_ttl](#extend_lock_ttl)
151
+ - [locks](#locks---get-list-of-obtained-locks)
152
+ - [queues](#queues---get-list-of-lock-request-queues)
153
+ - [keys](#keys---get-list-of-taken-locks-and-queues)
141
154
 
142
155
  ---
143
156
 
@@ -393,6 +406,94 @@ Return:
393
406
 
394
407
  ---
395
408
 
409
+ #### #extend_lock_ttl
410
+
411
+ - soon
412
+
413
+ ---
414
+
415
+ #### #locks - get list of obtained locks
416
+
417
+ - uses redis `SCAN` under the hood;
418
+ - accepts `scan_size:`/`Integer` option (`config[:key_extraction_batch_size]` by default);
419
+ - returns `Set<String>`
420
+
421
+ ```ruby
422
+ rql.locks # or rql.locks(scan_size: 123)
423
+
424
+ =>
425
+ #<Set:
426
+ {"rql:lock:locklock75",
427
+ "rql:lock:locklock9",
428
+ "rql:lock:locklock108",
429
+ "rql:lock:locklock7",
430
+ "rql:lock:locklock48",
431
+ "rql:lock:locklock104",
432
+ "rql:lock:locklock13",
433
+ "rql:lock:locklock62",
434
+ "rql:lock:locklock80",
435
+ "rql:lock:locklock28",
436
+ ...}>
437
+ ```
438
+
439
+ ---
440
+
441
+ #### #queues - get list of lock request queues
442
+
443
+ - uses redis `SCAN` under the hood;
444
+ - accepts `scan_size:`/`Integer` option (`config[:key_extraction_batch_size]` by default);
445
+ - returns `Set<String>`
446
+
447
+ ```ruby
448
+ rql.queues # or rql.queues(scan_size: 123)
449
+
450
+ =>
451
+ #<Set:
452
+ {"rql:lock_queue:locklock75",
453
+ "rql:lock_queue:locklock9",
454
+ "rql:lock_queue:locklock108",
455
+ "rql:lock_queue:locklock7",
456
+ "rql:lock_queue:locklock48",
457
+ "rql:lock_queue:locklock104",
458
+ "rql:lock_queue:locklock13",
459
+ "rql:lock_queue:locklock62",
460
+ "rql:lock_queue:locklock80",
461
+ "rql:lock_queue:locklock28",
462
+ ...}>
463
+ ```
464
+
465
+ ---
466
+
467
+ #### #keys - get list of taken locks and queues
468
+
469
+ - uses redis `SCAN` under the hood;
470
+ - accepts `scan_size:`/`Integer` option (`config[:key_extraction_batch_size]` by default);
471
+ - returns `Set<String>`
472
+
473
+ ```ruby
474
+ rql.keys # or rql.keys(scan_size: 123)
475
+
476
+ =>
477
+ #<Set:
478
+ {"rql:lock_queue:locklock75",
479
+ "rql:lock_queue:locklock9",
480
+ "rql:lock:locklock9",
481
+ "rql:lock_queue:locklock108",
482
+ "rql:lock_queue:locklock7",
483
+ "rql:lock:locklock7",
484
+ "rql:lock_queue:locklock48",
485
+ "rql:lock_queue:locklock104",
486
+ "rql:lock:locklock104",
487
+ "rql:lock_queue:locklock13",
488
+ "rql:lock_queue:locklock62",
489
+ "rql:lock_queue:locklock80",
490
+ "rql:lock:locklock80",
491
+ "rql:lock_queue:locklock28",
492
+ ...}>
493
+ ```
494
+
495
+ ---
496
+
396
497
  ## Instrumentation
397
498
 
398
499
  An instrumentation layer is incapsulated in `instrumenter` object stored in [config](#configuration) (`RedisQueuedLocks::Client#config[:instrumenter]`).
@@ -37,6 +37,7 @@ module RedisQueuedLocks::Acquier::Release
37
37
  RedisQueuedLocks::Resource::LOCK_QUEUE_PATTERN,
38
38
  count: batch_size
39
39
  ) do |lock_queue|
40
+ # TODO: reduce unnecessary iterations
40
41
  pipeline.call('ZREMRANGEBYSCORE', lock_queue, '-inf', '+inf')
41
42
  pipeline.call('EXPIRE', RedisQueuedLocks::Resource.lock_key_from_queue(lock_queue), '0')
42
43
  end
@@ -47,6 +48,7 @@ module RedisQueuedLocks::Acquier::Release
47
48
  RedisQueuedLocks::Resource::LOCK_PATTERN,
48
49
  count: batch_size
49
50
  ) do |lock_key|
51
+ # TODO: reduce unnecessary iterations
50
52
  pipeline.call('EXPIRE', lock_key, '0')
51
53
  end
52
54
  end
@@ -437,7 +437,66 @@ module RedisQueuedLocks::Acquier
437
437
  #
438
438
  # @api private
439
439
  # @since 0.1.0
440
- def extend_lock_ttl(redis_client, lock_name, milliseconds); end
440
+ def extend_lock_ttl(redis_client, lock_name, milliseconds)
441
+ # TODO: realize
442
+ end
443
+
444
+ # @param redis_client [RedisClient]
445
+ # @option scan_size [Integer]
446
+ # @return [Set<String>]
447
+ #
448
+ # @api private
449
+ # @since 0.1.0
450
+ def locks(redis_client, scan_size:)
451
+ Set.new.tap do |lock_keys|
452
+ redis_client.scan(
453
+ 'MATCH',
454
+ RedisQueuedLocks::Resource::LOCK_PATTERN,
455
+ count: scan_size
456
+ ) do |lock_key|
457
+ # TODO: reduce unnecessary iterations
458
+ lock_keys.add(lock_key)
459
+ end
460
+ end
461
+ end
462
+
463
+ # @param redis_client [RedisClient]
464
+ # @param scan_size [Integer]
465
+ # @return [Set<String>]
466
+ #
467
+ # @api private
468
+ # @since 0.1.0
469
+ def queues(redis_client, scan_size:)
470
+ Set.new.tap do |lock_queues|
471
+ redis_client.scan(
472
+ 'MATCH',
473
+ RedisQueuedLocks::Resource::LOCK_QUEUE_PATTERN,
474
+ count: scan_size
475
+ ) do |lock_queue|
476
+ # TODO: reduce unnecessary iterations
477
+ lock_queues.add(lock_queue)
478
+ end
479
+ end
480
+ end
481
+
482
+ # @param redis_client [RedisClient]
483
+ # @option scan_size [Integer]
484
+ # @return [Array<String>]
485
+ #
486
+ # @api private
487
+ # @since 0.1.0
488
+ def keys(redis_client, scan_size:)
489
+ Set.new.tap do |keys|
490
+ redis_client.scan(
491
+ 'MATCH',
492
+ RedisQueuedLocks::Resource::KEY_PATTERN,
493
+ count: scan_size
494
+ ) do |key|
495
+ # TODO: reduce unnecessary iterations
496
+ keys.add(key)
497
+ end
498
+ end
499
+ end
441
500
 
442
501
  private
443
502
 
@@ -15,6 +15,7 @@ class RedisQueuedLocks::Client
15
15
  setting :default_lock_ttl, 5_000 # NOTE: milliseconds
16
16
  setting :default_queue_ttl, 15 # NOTE: seconds
17
17
  setting :lock_release_batch_size, 100
18
+ setting :key_extraction_batch_size, 500
18
19
  setting :instrumenter, RedisQueuedLocks::Instrument::VoidNotifier
19
20
  setting :uniq_identifier, -> { RedisQueuedLocks::Resource.calc_uniq_identity }
20
21
 
@@ -225,5 +226,32 @@ class RedisQueuedLocks::Client
225
226
  def clear_locks(batch_size: config[:lock_release_batch_size])
226
227
  RedisQueuedLocks::Acquier.release_all_locks!(redis_client, batch_size, config[:instrumenter])
227
228
  end
229
+
230
+ # @option scan_size [Integer]
231
+ # @return [Set<String>]
232
+ #
233
+ # @api public
234
+ # @since 0.1.0
235
+ def locks(scan_size: config[:key_extraction_batch_size])
236
+ RedisQueuedLocks::Acquier.locks(redis_client, scan_size:)
237
+ end
238
+
239
+ # @option scan_size [Integer]
240
+ # @return [Set<String>]
241
+ #
242
+ # @api public
243
+ # @since 0.1.0
244
+ def queues(scan_size: config[:key_extraction_batch_size])
245
+ RedisQueuedLocks::Acquier.queues(redis_client, scan_size:)
246
+ end
247
+
248
+ # @option scan_size [Integer]
249
+ # @return [Set<String>]
250
+ #
251
+ # @api public
252
+ # @since 0.1.0
253
+ def keys(scan_size: config[:key_extraction_batch_size])
254
+ RedisQueuedLocks::Acquier.keys(redis_client, scan_size:)
255
+ end
228
256
  end
229
257
  # rubocop:enable Metrics/ClassLength
@@ -3,6 +3,12 @@
3
3
  # @api private
4
4
  # @since 0.1.0
5
5
  module RedisQueuedLocks::Resource
6
+ # @return [String]
7
+ #
8
+ # @api private
9
+ # @since 0.1.0
10
+ KEY_PATTERN = 'rql:lock*'
11
+
6
12
  # @return [String]
7
13
  #
8
14
  # @api private
@@ -5,6 +5,6 @@ module RedisQueuedLocks
5
5
  #
6
6
  # @api public
7
7
  # @since 0.0.1
8
- # @version 0.0.16
9
- VERSION = '0.0.16'
8
+ # @version 0.0.17
9
+ VERSION = '0.0.17'
10
10
  end
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: 0.0.16
4
+ version: 0.0.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Ibragimov