redis_queued_locks 0.0.32 → 0.0.34

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: d33fd5af73686a34765eb95c54fe9dc28b107a01768e41b2a28150dffdc72a60
4
- data.tar.gz: 0ac04f452fbd00b01df535a48dd724e360ed66f42459e33fbf989427531c6b6a
3
+ metadata.gz: 62b1870f7a71fb878167216b1f05a90f82c60b8a0da513dfad1edae8a87618a5
4
+ data.tar.gz: 705c1e47d0f4823e38f749f24e82700ce33d749e187c0ae98ff9bd5ff21aa142
5
5
  SHA512:
6
- metadata.gz: 419d36772547c3a7010353d6589b62c442cd7e2575a1c96fcf8ebcee9be83c002a44de7a5dc6de8faa6e32c76f044bf5eaf659ddaf156e8eb3093587dab54e90
7
- data.tar.gz: 28ba2de724d7d7540d967e9ade24ca6d65126af526224ae90f418c04e58618ff1aa856911d9eef363b004272fda73a0ce5ddf83a52460e4d78f09dabdd9fba3f
6
+ metadata.gz: cba6bd786d8db210d907bd5af41497aa3f34e026f2ecfb87f53e857f91d2278109c116a91bd767bffa4685c48f6a6d76be6054b93ffaea0e858f0d6a2ed29db1
7
+ data.tar.gz: 05fa884031b73de440c10442a46d2c328fb118d0e8c7447d241b6d5e2391408affddf964b7ae210038bc40f620009a38537cccbe418c9dc6ea562f7f50b76537
data/CHANGELOG.md CHANGED
@@ -1,20 +1,30 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.0.34] - 2024-03-26
4
+ ### Changed
5
+ - Removing the acquirer from the request queue during a lock obtaining logic now using more proper and accurate `ZREM` instead of `ZPOPMIN` for this;
6
+
7
+ ## [0.0.33] - 2024-03-26
8
+ ### Added
9
+ - Logging: added current lock data info to the detailed `#try_to_lock` log to the cases when lock is still obtained. It is suitable
10
+ when you pass a custom metadata with lock obtainer (for example: the current string of code) and want to see this information
11
+ in logs when you can not acquire the concrete lock long time;
12
+
3
13
  ## [0.0.32] - 2024-03-26
4
14
  ### Added
5
15
  - Support for custom metadata that merged to the lock data. This data also returned from `RedisQueudLocks::Client#lock_info` method;
6
- - Custom metadata shou;d be represented as a `key => value` `Hash` data (or `NilClass` instead);
16
+ - Custom metadata should be represented as a `key => value` `Hash` (`nil` by default);
7
17
  - Custom metadata values is returned as raw data from Redis (commonly as strings);
8
18
  - Custom metadata can not contain reserved lock data keys;
9
19
  - Reduced some memory consuption;
10
20
  ### Changed
11
- - `RedisQueuedLocks::Client#lock_info` - has keys is changed from `Symbol` type to `String` type;
12
- - `RedisQueuedLocks::Client#queue_info` - hash keys is changed from `Symbol` type to `String` type;
21
+ - `RedisQueuedLocks::Client#lock_info`: hash key types of method result is changed from `Symbol` type to `String` type;
22
+ - `RedisQueuedLocks::Client#queue_info`: hash key types of method result is changed from `Symbol` type to `String` type;
13
23
 
14
24
  ## [0.0.31] - 2024-03-25
15
25
  ### Changed
16
26
  - `:metadata` renamed to `:instrument` in order to reflect it's domain area;
17
- - `:metadata` is renamed to `:meta` and reserved for the future updates;
27
+ - `:metadata` is renamed to `:meta` and reserved for future updates;
18
28
 
19
29
  ## [0.0.30] - 2024-03-23
20
30
  ### Fixed
data/README.md CHANGED
@@ -108,7 +108,7 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
108
108
  config.default_lock_ttl = 5_000
109
109
 
110
110
  # (seconds) (default: 15)
111
- # - lock request timeout. after this timeout your lock request in queue will be requeued;
111
+ # - lock request timeout. after this timeout your lock request in queue will be requeued with new position (at the end of the queue);
112
112
  config.default_queue_ttl = 15
113
113
 
114
114
  # (default: 100)
@@ -140,19 +140,27 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
140
140
  # (default: RedisQueuedLocks::Logging::VoidLogger)
141
141
  # - the logger object;
142
142
  # - should implement `debug(progname = nil, &block)` (minimal requirement) or be an instance of Ruby's `::Logger` class/subclass;
143
- # - at this moment the only debug logs are realised in 3 cases:
144
- # - start of lock obtaining: "[redis_queud_locks.start_lock_obtaining] lock_key => 'rql:lock:your_lock' acq_id => 'rql:acq:54307/3620/3640/3540/c1799ede93'"
145
- # - finish of the lock obtaining: "[redis_queued_locks.lock_obtained] lock_key => 'rql:lock:your_lock' acq_id => 'rql:acq:54307/3620/3640/3540/c1799ede93' acq_time => 123.456 (ms)"
146
- # - start of the lock expiration after `yield`: "[redis_queud_locks.expire_lock] lock_key => 'rql:lock:your_lock' acq_id => 'rql:acq:54307/3620/3640/3540/c1799ede93'"
143
+ # - at this moment the only debug logs are realised in following cases:
144
+ # - "[redis_queued_locks.start_lock_obtaining]" (logs "lock_key", "queue_ttl", "acq_id");
145
+ # - "[redis_queued_locks.start_try_to_lock_cycle]" (logs "lock_key", "queue_ttl", "acq_id");
146
+ # - "[redis_queued_locks.dead_score_reached__reset_acquier_position]" (logs "lock_key", "queue_ttl", "acq_id");
147
+ # - "[redis_queued_locks.lock_obtained]" (logs "lockkey", "queue_ttl", "acq_id", "acq_time");
147
148
  # - by default uses VoidLogger that does nothing;
148
149
  config.logger = RedisQueuedLocks::Logging::VoidLogger
149
150
 
150
151
  # (default: false)
151
- # - should be logged the each internal try-retry lock acquire (a lot of logs can be generated depending on your retry configurations);
152
- # - it adds 2 cases to the log in addition to the existing 3:
153
- # - start of a try: "[redis_queud_locks.try_lock_start] lock_key => 'rql:lock:your_lock' acq_id => 'rql:acq:54307/3620/3640/3540/c1799ede93'"
154
- # - redis connection is feteched from the pool after "start of a try": "[redis_queued_locks.try_lock_rconn_fetched] lock_key => 'rql:lock:your_lock' acq_id => 'rql:acq:54307/3620/3640/3540/c1799ede93'"
155
- # - if logger is not configured this option does not lead to any effect;
152
+ # - adds additional debug logs;
153
+ # - enables additional logs for each internal try-retry lock acquiring (a lot of logs can be generated depending on your retry configurations);
154
+ # - it adds following logs in addition to the existing:
155
+ # - "[redis_queued_locks.try_lock.start]" (logs "lock_key", "queue_ttl", "acq_id");
156
+ # - "[redis_queued_locks.try_lock.rconn_fetched]" (logs "lock_key", "queue_ttl", "acq_id");
157
+ # - "[redis_queued_locks.try_lock.acq_added_to_queue]" (logs "lock_key", "queue_ttl", "acq_id)";
158
+ # - "[redis_queued_locks.try_lock.remove_expired_acqs]" (logs "lock_key", "queue_ttl", "acq_id");
159
+ # - "[redis_queued_locks.try_lock.get_first_from_queue]" (logs "lock_key", "queue_ttl", "acq_id", "first_acq_id_in_queue");
160
+ # - "[redis_queued_locks.try_lock.exit__queue_ttl_reached]" (logs "lock_key", "queue_ttl", "acq_id");
161
+ # - "[redis_queued_locks.try_lock.exit__no_first]" (logs "lock_key", "queue_ttl", "acq_id", "first_acq_id_in_queue", "<current_lock_data>");
162
+ # - "[redis_queued_locks.try_lock.exit__still_obtained]" (logs "lock_key", "queue_ttl", "acq_id", "first_acq_id_in_queue", "locked_by_acq_id", "<current_lock_data>");
163
+ # - "[redis_queued_locks.try_lock.run__free_to_acquire]" (logs "lock_key", "queue_ttl", "acq_id");
156
164
  config.log_lock_try = false
157
165
  end
158
166
  ```
@@ -321,8 +329,7 @@ See `#lock` method [documentation](#lock---obtain-a-lock).
321
329
  - `"ts"` - `integer`/`epoch` - the time lock was obtained;
322
330
  - `"init_ttl"` - `integer` - (milliseconds) initial lock key ttl;
323
331
  - `"rem_ttl"` - `integer` - (milliseconds) remaining lock key ttl;
324
- - custom metadata keys - `String` - custom metadata passed to the `lock`/`lock!`
325
- methods via `meta:` keyword argument (see [lock]((#lock---obtain-a-lock)) method documentation);
332
+ - `custom metadata`- `string`/`integer` - custom metadata passed to the `lock`/`lock!` methods via `meta:` keyword argument (see [lock]((#lock---obtain-a-lock)) method documentation);
326
333
 
327
334
  ```ruby
328
335
  # without custom metadata
@@ -631,16 +638,14 @@ Detalized event semantics and payload structure:
631
638
  - `100%` test coverage;
632
639
  - per-block-holding-the-lock sidecar `Ractor` and `in progress queue` in RedisDB that will extend
633
640
  the acquired lock for long-running blocks of code (that invoked "under" the lock
634
- whose ttl may expire before the block execution completes). It only makes sens for non-`timed` locks
635
- (for those locks where otaned with `timed: false` option);
636
- - an ability to add custom metadata to the lock and an ability to read this data;
641
+ whose ttl may expire before the block execution completes). It only makes sense for non-`timed` locks;
637
642
  - lock prioritization;
638
643
  - support for LIFO strategy;
639
- - structured logging;
644
+ - structured logging (separated docs);
640
645
  - GitHub Actions CI;
641
646
  - `RedisQueuedLocks::Acquier::Try.try_to_lock` - detailed successful result analization;
642
647
  - better code stylization and interesting refactorings;
643
- - dead queue cleanup;
648
+ - dead queue keys cleanup (empty queues);
644
649
  - statistics with UI;
645
650
  - support for `Dragonfly` DB backend;
646
651
  - support for `Garnet` DB backend;
@@ -46,7 +46,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
46
46
  "[redis_queued_locks.try_lock.start] " \
47
47
  "lock_key => '#{lock_key}' " \
48
48
  "queue_ttl => #{queue_ttl} " \
49
- "acq_id => '#{acquier_id}' "
49
+ "acq_id => '#{acquier_id}'"
50
50
  )
51
51
  end
52
52
  end
@@ -64,7 +64,9 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
64
64
  end
65
65
  end
66
66
 
67
- # Step 0: watch the lock key changes (and discard acquirement if lock is already acquired)
67
+ # Step 0:
68
+ # watch the lock key changes (and discard acquirement if lock is already
69
+ # obtained by another acquier during the current lock acquiremntt)
68
70
  rconn.multi(watch: [lock_key]) do |transact|
69
71
  # Fast-Step X0: fail-fast check
70
72
  if fail_fast && rconn.call('HGET', lock_key, 'acq_id')
@@ -163,7 +165,8 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
163
165
  "lock_key => '#{lock_key}' " \
164
166
  "queue_ttl => #{queue_ttl} " \
165
167
  "acq_id => '#{acquier_id}' " \
166
- "first_acq_id_in_queue => '#{waiting_acquier}'"
168
+ "first_acq_id_in_queue => '#{waiting_acquier}' " \
169
+ "<current_lock_data> => <<#{rconn.call('HGETALL', lock_key).to_h}>>"
167
170
  )
168
171
  end
169
172
  end
@@ -199,7 +202,8 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
199
202
  "queue_ttl => #{queue_ttl} " \
200
203
  "acq_id => '#{acquier_id}' " \
201
204
  "first_acq_id_in_queue => '#{waiting_acquier}' " \
202
- "locked_by_acq_id => '#{locked_by_acquier}'"
205
+ "locked_by_acq_id => '#{locked_by_acquier}' " \
206
+ "<current_lock_data> => <<#{rconn.call('HGETALL', lock_key).to_h}>>"
203
207
  )
204
208
  end
205
209
  end
@@ -214,7 +218,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
214
218
  # NOTE: required lock is free and ready to be acquired! acquire!
215
219
 
216
220
  # Step 6.1: remove our acquier from waiting queue
217
- transact.call('ZPOPMIN', lock_key_queue, '1')
221
+ transact.call('ZREM', lock_key_queue, acquier_id)
218
222
 
219
223
  RedisQueuedLocks.debug(
220
224
  'Step №4: Забираем наш текущий процесс из очереди. [ZPOPMIN]'
@@ -5,6 +5,6 @@ module RedisQueuedLocks
5
5
  #
6
6
  # @api public
7
7
  # @since 0.0.1
8
- # @version 0.0.32
9
- VERSION = '0.0.32'
8
+ # @version 0.0.34
9
+ VERSION = '0.0.34'
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: 0.0.32
4
+ version: 0.0.34
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-03-25 00:00:00.000000000 Z
11
+ date: 2024-03-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis-client