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,6 +2,7 @@
2
2
 
3
3
  # @api private
4
4
  # @since 1.7.0
5
+ # @version 1.22.0
5
6
  # rubocop:disable Metrics/ModuleLength
6
7
  module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
7
8
  # rubocop:disable Metrics/ClassLength
@@ -348,11 +349,12 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
348
349
  # @param host_id [String]
349
350
  # @param access_strategy [Symbol]
350
351
  # @param rw_mode [Symbol]
352
+ # @param priority [Integer] The lock request priority.
351
353
  # @return [void]
352
354
  #
353
355
  # @api private
354
356
  # @since 1.7.0
355
- # @version 1.18.0
357
+ # @version 1.22.0
356
358
  def acq_added_to_queue(
357
359
  logger,
358
360
  log_sampled,
@@ -362,7 +364,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
362
364
  acquirer_id,
363
365
  host_id,
364
366
  access_strategy,
365
- rw_mode
367
+ rw_mode,
368
+ priority
366
369
  )
367
370
  return unless log_sampled && log_lock_try
368
371
 
@@ -373,7 +376,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
373
376
  "acq_id => '#{acquirer_id}' " \
374
377
  "hst_id => '#{host_id}' " \
375
378
  "acs_strat => '#{access_strategy}' " \
376
- "rw_mode => '#{rw_mode}'"
379
+ "rw_mode => '#{rw_mode}' " \
380
+ "priority => #{priority}"
377
381
  end rescue nil
378
382
  end
379
383
 
@@ -415,6 +419,52 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
415
419
  end rescue nil
416
420
  end
417
421
 
422
+ # (priorities) A dead lock request of another priority band blocked the lock request: it is
423
+ # dropped with all dead lock requests of its band (both lock queues).
424
+ #
425
+ # @param logger [::Logger,#debug]
426
+ # @param log_sampled [Boolean]
427
+ # @param log_lock_try [Boolean]
428
+ # @param lock_key [String]
429
+ # @param queue_ttl [Integer]
430
+ # @param acquirer_id [String]
431
+ # @param host_id [String]
432
+ # @param access_strategy [Symbol]
433
+ # @param rw_mode [Symbol]
434
+ # @param dead_acquirer [String] The acquirer of the dropped blocking lock request.
435
+ # @param dead_priority [Integer] The priority of the dropped blocking lock request.
436
+ # @return [void]
437
+ #
438
+ # @api private
439
+ # @since 1.22.0
440
+ def dead_request_removed(
441
+ logger,
442
+ log_sampled,
443
+ log_lock_try,
444
+ lock_key,
445
+ queue_ttl,
446
+ acquirer_id,
447
+ host_id,
448
+ access_strategy,
449
+ rw_mode,
450
+ dead_acquirer,
451
+ dead_priority
452
+ )
453
+ return unless log_sampled && log_lock_try
454
+
455
+ logger.debug do
456
+ "[redis_queued_locks.try_lock.dead_request_removed] " \
457
+ "lock_key => '#{lock_key}' " \
458
+ "queue_ttl => #{queue_ttl} " \
459
+ "acq_id => '#{acquirer_id}' " \
460
+ "hst_id => '#{host_id}' " \
461
+ "acs_strat => '#{access_strategy}' " \
462
+ "rw_mode => '#{rw_mode}' " \
463
+ "dead_acq_id => '#{dead_acquirer}' " \
464
+ "dead_priority => #{dead_priority}"
465
+ end rescue nil
466
+ end
467
+
418
468
  # @param logger [::Logger,#debug]
419
469
  # @param log_sampled [Boolean]
420
470
  # @param log_lock_try [Boolean]
@@ -425,11 +475,14 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
425
475
  # @param access_strategy [Symbol]
426
476
  # @param rw_mode [Symbol]
427
477
  # @param waiting_acquirer [String,NilClass]
478
+ # @param waiting_priority [Integer,NilClass]
479
+ # The priority of the first request (decoded for logs only: `nil` without logs and
480
+ # without the first request; logged as `nil` without the first request).
428
481
  # @return [void]
429
482
  #
430
483
  # @api private
431
484
  # @since 1.7.0
432
- # @version 1.18.0
485
+ # @version 1.22.0
433
486
  def get_first_from_queue(
434
487
  logger,
435
488
  log_sampled,
@@ -440,7 +493,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
440
493
  host_id,
441
494
  access_strategy,
442
495
  rw_mode,
443
- waiting_acquirer
496
+ waiting_acquirer,
497
+ waiting_priority
444
498
  )
445
499
  return unless log_sampled && log_lock_try
446
500
 
@@ -452,7 +506,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
452
506
  "hst_id => '#{host_id}' " \
453
507
  "acs_strat => '#{access_strategy}' " \
454
508
  "rw_mode => '#{rw_mode}' " \
455
- "first_acq_id_in_queue => '#{waiting_acquirer}'"
509
+ "first_acq_id_in_queue => '#{waiting_acquirer}' " \
510
+ "first_priority_in_queue => #{waiting_priority.inspect}"
456
511
  end rescue nil
457
512
  end
458
513
 
@@ -504,12 +559,14 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
504
559
  # @param access_strategy [Symbol]
505
560
  # @param rw_mode [Symbol]
506
561
  # @param waiting_acquirer [String,NilClass]
562
+ # @param waiting_priority [Integer,NilClass]
563
+ # The priority of the first request (decoded for logs only: `nil` without logs).
507
564
  # @param current_lock_data [Hash<String,Any>]
508
565
  # @return [void]
509
566
  #
510
567
  # @api private
511
568
  # @since 1.7.0
512
- # @version 1.18.0
569
+ # @version 1.22.0
513
570
  def exit__no_first(
514
571
  logger,
515
572
  log_sampled,
@@ -521,6 +578,7 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
521
578
  access_strategy,
522
579
  rw_mode,
523
580
  waiting_acquirer,
581
+ waiting_priority,
524
582
  current_lock_data
525
583
  )
526
584
  return unless log_sampled && log_lock_try
@@ -534,6 +592,7 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
534
592
  "acs_strat => '#{access_strategy}' " \
535
593
  "rw_mode => '#{rw_mode}' " \
536
594
  "first_acq_id_in_queue => '#{waiting_acquirer}' " \
595
+ "first_priority_in_queue => #{waiting_priority.inspect} " \
537
596
  "<current_lock_data> => <<#{current_lock_data}>>"
538
597
  end rescue nil
539
598
  end
@@ -548,13 +607,15 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
548
607
  # @param access_strategy [Symbol]
549
608
  # @param rw_mode [Symbol]
550
609
  # @param waiting_acquirer [String,NilClass]
610
+ # @param waiting_priority [Integer,NilClass]
611
+ # The priority of the first request (decoded for logs only: `nil` without logs).
551
612
  # @param locked_by_acquirer [String]
552
613
  # @param current_lock_data [Hash<String,Any>]
553
614
  # @return [void]
554
615
  #
555
616
  # @api private
556
617
  # @since 1.7.0
557
- # @version 1.18.0
618
+ # @version 1.22.0
558
619
  def exit__lock_still_obtained(
559
620
  logger,
560
621
  log_sampled,
@@ -566,6 +627,7 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
566
627
  access_strategy,
567
628
  rw_mode,
568
629
  waiting_acquirer,
630
+ waiting_priority,
569
631
  locked_by_acquirer,
570
632
  current_lock_data
571
633
  )
@@ -580,6 +642,7 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
580
642
  "acs_strat => '#{access_strategy}' " \
581
643
  "rw_mode => '#{rw_mode}' " \
582
644
  "first_acq_id_in_queue => '#{waiting_acquirer}' " \
645
+ "first_priority_in_queue => #{waiting_priority.inspect} " \
583
646
  "locked_by_acq_id => '#{locked_by_acquirer}' " \
584
647
  "<current_lock_data> => <<#{current_lock_data}>>"
585
648
  end rescue nil
@@ -597,10 +660,13 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
597
660
  # @param access_strategy [Symbol]
598
661
  # @param rw_mode [Symbol]
599
662
  # @param ahead_acquirer [String]
663
+ # @param ahead_priority [Integer,NilClass]
664
+ # The priority of the request ahead (decoded for logs only: `nil` without logs).
600
665
  # @return [void]
601
666
  #
602
667
  # @api private
603
668
  # @since 1.18.0
669
+ # @version 1.22.0
604
670
  def exit__write_request_ahead(
605
671
  logger,
606
672
  log_sampled,
@@ -611,7 +677,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
611
677
  host_id,
612
678
  access_strategy,
613
679
  rw_mode,
614
- ahead_acquirer
680
+ ahead_acquirer,
681
+ ahead_priority
615
682
  )
616
683
  return unless log_sampled && log_lock_try
617
684
 
@@ -623,7 +690,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
623
690
  "hst_id => '#{host_id}' " \
624
691
  "acs_strat => '#{access_strategy}' " \
625
692
  "rw_mode => '#{rw_mode}' " \
626
- "ahead_acq_id => '#{ahead_acquirer}'"
693
+ "ahead_acq_id => '#{ahead_acquirer}' " \
694
+ "ahead_priority => #{ahead_priority}"
627
695
  end rescue nil
628
696
  end
629
697
 
@@ -639,10 +707,13 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
639
707
  # @param access_strategy [Symbol]
640
708
  # @param rw_mode [Symbol]
641
709
  # @param ahead_acquirer [String]
710
+ # @param ahead_priority [Integer,NilClass]
711
+ # The priority of the request ahead (decoded for logs only: `nil` without logs).
642
712
  # @return [void]
643
713
  #
644
714
  # @api private
645
715
  # @since 1.18.0
716
+ # @version 1.22.0
646
717
  def exit__read_request_ahead(
647
718
  logger,
648
719
  log_sampled,
@@ -653,7 +724,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
653
724
  host_id,
654
725
  access_strategy,
655
726
  rw_mode,
656
- ahead_acquirer
727
+ ahead_acquirer,
728
+ ahead_priority
657
729
  )
658
730
  return unless log_sampled && log_lock_try
659
731
 
@@ -665,7 +737,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
665
737
  "hst_id => '#{host_id}' " \
666
738
  "acs_strat => '#{access_strategy}' " \
667
739
  "rw_mode => '#{rw_mode}' " \
668
- "ahead_acq_id => '#{ahead_acquirer}'"
740
+ "ahead_acq_id => '#{ahead_acquirer}' " \
741
+ "ahead_priority => #{ahead_priority}"
669
742
  end rescue nil
670
743
  end
671
744
 
@@ -682,10 +755,13 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
682
755
  # @param access_strategy [Symbol]
683
756
  # @param rw_mode [Symbol]
684
757
  # @param waiting_acquirer [String,NilClass]
758
+ # @param waiting_priority [Integer,NilClass]
759
+ # The priority of the first request (decoded for logs only: `nil` without logs).
685
760
  # @return [void]
686
761
  #
687
762
  # @api private
688
763
  # @since 1.18.0
764
+ # @version 1.22.0
689
765
  def exit__read_lock_still_obtained(
690
766
  logger,
691
767
  log_sampled,
@@ -696,7 +772,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
696
772
  host_id,
697
773
  access_strategy,
698
774
  rw_mode,
699
- waiting_acquirer
775
+ waiting_acquirer,
776
+ waiting_priority
700
777
  )
701
778
  return unless log_sampled && log_lock_try
702
779
 
@@ -708,7 +785,8 @@ module RedisQueuedLocks::Acquirer::AcquireLock::TryToLock::LogVisitor
708
785
  "hst_id => '#{host_id}' " \
709
786
  "acs_strat => '#{access_strategy}' " \
710
787
  "rw_mode => '#{rw_mode}' " \
711
- "first_acq_id_in_queue => '#{waiting_acquirer}'"
788
+ "first_acq_id_in_queue => '#{waiting_acquirer}' " \
789
+ "first_priority_in_queue => #{waiting_priority.inspect}"
712
790
  end rescue nil
713
791
  end
714
792