redis_queued_locks 1.11.0 → 1.12.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c7161dbfaa5660709705978e003201b12c4684d5c271fc700710802b10586e00
4
- data.tar.gz: efaf7103b6bddfd708aceca2d967f282e60b6a74b43c7de2314512cdc963fd19
3
+ metadata.gz: 419bb42dc0f90c9cfac1107f3eb93ab4e5185d17efa53f78012eed09aee03931
4
+ data.tar.gz: c9e1471bc65375cbabe88276c7144460b05bb3e0cb4880a75b061514578a4e3d
5
5
  SHA512:
6
- metadata.gz: 4736b2cf3ec4fa9a121425769a5037aa78d2f5765829533fd4cb830f3e184b856d03a5fc2e7653df3a49c47975de074120f55ddc88476d78b623131ffc718f48
7
- data.tar.gz: eb2e86d9764606a11f7c547e8e1ff6b126a26a3cbfd3ea6cff0f670625d6845a441eb7ef6ad9c0e9ce125e0f5fb983feb068205b04bb5a27b85307d5119140d9
6
+ metadata.gz: aa5e610820ffb105003d09918ee5df8c51989de24a0473eb0d9056deb5e0c2de0cc8c23c220bd4b8da14a7ff0d2b2c7271cc521862263251c03382d4f246f302
7
+ data.tar.gz: dc14d292c361c798c1cd5a375ff48f271d96a35246c2e463d331dfe9dcb116b64f3b17ad95e12a5e5f72f8aad2a243a17cc0ed10a2ab4521773385bc51d2c77d
data/CHANGELOG.md CHANGED
@@ -1,6 +1,20 @@
1
1
  ## [Unreleased]
2
2
 
3
- ### [1.11.0] - 2024-08-11
3
+ ## [1.12.1]
4
+ ### Changed
5
+ - Internal Private API: an internal Reentrant's Lock utility (`RedisQueuedLocks::Utilities::Lock`) basis
6
+ is changed from `::Mutex` to `::Monitor` in order to use Ruby's Core C-based
7
+ implementation (prevent some Ruby-runtime based GVL-oriented locking) of re-entrant locks
8
+ instead of the custom Ruby-based implementation;
9
+ ### Fixed
10
+ - `redis_queued_locks.lock_hold_and_release` instrumentation event has incorrect `acq_time` payload value
11
+ (it incorrectly stores `lock_key` payload value);
12
+
13
+ ## [1.12.0] - 2024-08-11
14
+ ### Changed
15
+ - Timed blocks of code and their timeout errors: reduced error message object allocations;
16
+
17
+ ## [1.11.0] - 2024-08-11
4
18
  ### Changed
5
19
  - Lock Acquierment Timeout (`acq_timeout`/`queue_ttl`): more correct timeout error interception
6
20
  inside the `RedisQueuedLocks::Acquier::AcquireLock::WithAcqTimeout` logic that now raises and
data/README.md CHANGED
@@ -2073,25 +2073,34 @@ Detalized event semantics and payload structure:
2073
2073
  trying to ressurect unexpectedly terminated swarm elements, and will notify about this;
2074
2074
  - swarm logs (thread/ractor has some limitations so the initial implementation does not include swarm logging);
2075
2075
  - swarm instrumentation (thread/ractor has some limitations so the initial implementation does not include swarm instrumentation);
2076
+ - isolated timeouts which are independent of internal Ruby's timeout implementation (where all timeouts are hostend inside
2077
+ the global "timeout request" queue and managed by a single global "timeout wathcer" thread). it should prevent any logic and timeout intersections,
2078
+ some GVL-related things and problem situations when the global watcher thread is "dead";
2076
2079
  - lock request prioritization;
2077
- - **strict redlock algorithm support** (support for many `RedisClient` instances);
2080
+ - **strict redlock algorithm support** (support for many `RedisClient` instances that are fully independent (distributed redis instances));
2078
2081
  - `#lock_series` - acquire a series of locks:
2079
2082
  ```ruby
2080
2083
  rql.lock_series('lock_a', 'lock_b', 'lock_c') { puts 'locked' }
2081
2084
  ```
2082
- - support for `Dragonfly` database backend (https://github.com/dragonflydb/dragonfly) (https://www.dragonflydb.io/);
2085
+ - `light mode`: an ability to work without any debug and instrumentation logic and data (totally reduced debugging and instrumenting possibilities, but better performance);
2083
2086
  - **Minor**:
2087
+ - support for `Dragonfly` database backend (https://github.com/dragonflydb/dragonfly) (https://www.dragonflydb.io/);
2088
+ - (_research_) GVL-isolation for lock acquirement logic (try to bypass Ruby's "context-switching" in order to prevent any time-based affects on lock-acquirement logic);
2084
2089
  - Semantic error objects for unexpected Redis errors;
2085
2090
  - **Experimental feature**: (non-`timed` locks): per-ruby-block-holding-the-lock sidecar `Ractor` and `in progress queue` in RedisDB that will extend
2086
2091
  the acquired lock for long-running blocks of code (that invoked "under" the lock
2087
2092
  whose ttl may expire before the block execution completes). It makes sense for non-`timed` locks *only*;
2093
+ - sized lock queues (with an ability of dynamically growing size);
2088
2094
  - better code stylization (+ some refactorings);
2089
2095
  - `RedisQueuedLocks::Acquier::Try.try_to_lock` - detailed successful result analization;
2090
2096
  - Support for LIFO strategy;
2091
2097
  - better specs with 100% test coverage (total specs rework);
2092
2098
  - statistics with UI;
2093
2099
  - JSON log formatter;
2100
+ - RBS type signatures;
2101
+ - **automatic** deadlock detection;
2094
2102
  - `go`-lang implementation;
2103
+ - (_research_) simplification and speedup of the internal "redis-communuication-and-data-storing"-based algorithms;
2095
2104
 
2096
2105
  ---
2097
2106
 
@@ -19,6 +19,8 @@ module RedisQueuedLocks::Acquier::AcquireLock::WithAcqTimeout
19
19
  # Callback invoked on Timeout::Error.
20
20
  # @return [Any]
21
21
  #
22
+ # @raise [RedisQueuedLocks::LockAcquiermentIntermediateTimeoutError]
23
+ #
22
24
  # @api private
23
25
  # @since 1.0.0
24
26
  # @version 1.11.0
@@ -32,10 +34,6 @@ module RedisQueuedLocks::Acquier::AcquireLock::WithAcqTimeout
32
34
  on_timeout: nil,
33
35
  &block
34
36
  )
35
- # TODO:
36
- # think about the runtime error class-object creation that perevent any timeout error
37
- # interception collisions (but remember: it can lead to regular internal ruby method/constant
38
- # cache invalidation);
39
37
  ::Timeout.timeout(timeout, RedisQueuedLocks::LockAcquiermentIntermediateTimeoutError, &block)
40
38
  rescue RedisQueuedLocks::LockAcquiermentIntermediateTimeoutError
41
39
  on_timeout.call unless on_timeout == nil
@@ -107,28 +107,22 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldExpire
107
107
  # @param block [Blcok]
108
108
  # @return [Any]
109
109
  #
110
+ # @raise [RedisQueuedLocks::TimedLockTimeoutError]
111
+ #
110
112
  # @api private
111
113
  # @since 1.3.0
112
- # @version 1.10.0
114
+ # @version 1.12.0
113
115
  def yield_with_timeout(timeout, lock_key, lock_ttl, acquier_id, host_id, meta, &block)
114
- ::Timeout.timeout(
115
- timeout,
116
+ ::Timeout.timeout(timeout, RedisQueuedLocks::TimedLockIntermediateTimeoutError, &block)
117
+ rescue RedisQueuedLocks::TimedLockIntermediateTimeoutError
118
+ raise(
116
119
  RedisQueuedLocks::TimedLockTimeoutError,
117
- # NOTE:
118
- # - this string is generated on each invocation cuz we need to raise custom exception
119
- # from the Timeout API in order to prevent incorred Timeout::Error interception when
120
- # the intercepted error is caused from the block not from the RQL;
121
- # - we can't omit this string object creation at the moment via original Ruby's Timeout API;
122
- # TODO:
123
- # - refine Timeout#timeout (via Ruby's Refinement API) in order to provide lazy exception
124
- # message initialization;
125
120
  "Passed <timed> block of code exceeded the lock TTL " \
126
121
  "(lock: \"#{lock_key}\", " \
127
122
  "ttl: #{lock_ttl}, " \
128
123
  "meta: #{meta ? meta.inspect : '<no-meta>'}, " \
129
124
  "acq_id: \"#{acquier_id}\", " \
130
- "hst_id: \"#{host_id}\")",
131
- &block
125
+ "hst_id: \"#{host_id}\")"
132
126
  )
133
127
  end
134
128
  end
@@ -154,7 +154,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
154
154
  #
155
155
  # @api private
156
156
  # @since 1.0.0
157
- # @version 1.9.0
157
+ # @version 1.12.1
158
158
  def acquire_lock(
159
159
  redis,
160
160
  lock_name,
@@ -531,8 +531,8 @@ module RedisQueuedLocks::Acquier::AcquireLock
531
531
  acq_process[:lock_info][:acq_id],
532
532
  acq_process[:lock_info][:hst_id],
533
533
  acq_process[:lock_info][:ts],
534
- acq_process[:lock_info][:lock_key],
535
534
  acq_process[:acq_time],
535
+ acq_process[:hold_time],
536
536
  instrument
537
537
  )
538
538
  end
@@ -25,6 +25,10 @@ module RedisQueuedLocks
25
25
  # @since 1.0.0
26
26
  LockAcquiermentRetryLimitError = Class.new(Error)
27
27
 
28
+ # @api private
29
+ # @since 1.12.0
30
+ TimedLockIntermediateTimeoutError = Class.new(::Timeout::Error)
31
+
28
32
  # @api pulic
29
33
  # @since 1.0.0
30
34
  TimedLockTimeoutError = Class.new(Error)
@@ -7,8 +7,9 @@ class RedisQueuedLocks::Utilities::Lock
7
7
  #
8
8
  # @api private
9
9
  # @since 1.9.0
10
+ # @version 1.13.0
10
11
  def initialize
11
- @lock = ::Mutex.new
12
+ @lock = ::Monitor.new
12
13
  end
13
14
 
14
15
  # @param block [Block]
@@ -16,7 +17,8 @@ class RedisQueuedLocks::Utilities::Lock
16
17
  #
17
18
  # @api private
18
19
  # @since 1.9.0
20
+ # @version 1.13.0
19
21
  def synchronize(&block)
20
- @lock.owned? ? yield : @lock.synchronize(&block)
22
+ @lock.synchronize(&block)
21
23
  end
22
24
  end
@@ -5,6 +5,6 @@ module RedisQueuedLocks
5
5
  #
6
6
  # @api public
7
7
  # @since 0.0.1
8
- # @version 1.11.0
9
- VERSION = '1.11.0'
8
+ # @version 1.12.1
9
+ VERSION = '1.12.1'
10
10
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis_queued_locks
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rustam Ibragimov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-11 00:00:00.000000000 Z
11
+ date: 2024-09-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client
@@ -135,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
135
135
  - !ruby/object:Gem::Version
136
136
  version: '0'
137
137
  requirements: []
138
- rubygems_version: 3.5.11
138
+ rubygems_version: 3.5.17
139
139
  signing_key:
140
140
  specification_version: 4
141
141
  summary: Distributed locks with "prioritized lock acquisition queue" capabilities