redis_queued_locks 0.0.26 → 0.0.28
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 -1
- data/README.md +8 -5
- data/lib/redis_queued_locks/acquier/acquire_lock/try_to_lock.rb +2 -2
- data/lib/redis_queued_locks/acquier/acquire_lock/yield_with_expire.rb +7 -2
- data/lib/redis_queued_locks/acquier/acquire_lock.rb +2 -2
- data/lib/redis_queued_locks/acquier/lock_info.rb +2 -2
- data/lib/redis_queued_locks/resource.rb +4 -4
- data/lib/redis_queued_locks/version.rb +2 -2
- 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: 5de2915b0828a1c82327dd301b41388cc649b2b922ca18f98cde7e8607753b28
|
4
|
+
data.tar.gz: da86f22a9ed5a834467ae80d9596c9efb0be1e645546c5b32a8f5d5b1dcec294
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f3a60c00b200f9e474ad0471e8e59541786f6e035df4c4d93d553eb93456fc99f0743970d3154fa8d3878a4e67b03d8d2ae2c16b71336b8d277f886dd4821e4
|
7
|
+
data.tar.gz: 1b52f00d36d568dce68b14caa0cbfb0e1ec793a7eec9adeb5bbca3c042b8bd224cec5f74488c4f0b34de0b302ec98392584a07e21bd02f106a370f3341ef3a35
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.0.28] - 2024-03-21
|
4
|
+
### Added
|
5
|
+
- Logging: added `acq_id` to every log message;
|
6
|
+
- Logging: updated documentation;
|
7
|
+
|
8
|
+
## [0.0.27] - 2024-03-21
|
9
|
+
### Changed
|
10
|
+
- Better acquier position accuracy: acquier position in lock queue
|
11
|
+
should be represented as EPOCH in seconds+microseconds (previously: simply in seconds);
|
12
|
+
|
3
13
|
## [0.0.26] - 2024-03-21
|
4
14
|
### Added
|
5
15
|
- Logging: add `acquier_id`;
|
@@ -14,7 +24,7 @@
|
|
14
24
|
|
15
25
|
## [0.0.23] - 2024-03-21
|
16
26
|
### Changed
|
17
|
-
- Composed redis commands are invoked
|
27
|
+
- Composed redis commands are invoked from the same *one* conenction
|
18
28
|
(instead of mutiple connection fetching from redis connection pool on each redis command);
|
19
29
|
|
20
30
|
## [0.0.22] - 2024-03-21
|
data/README.md
CHANGED
@@ -139,15 +139,18 @@ clinet = RedisQueuedLocks::Client.new(redis_client) do |config|
|
|
139
139
|
# - the logger object;
|
140
140
|
# - should implement `debug(progname = nil, &block)` (minimal requirement) or be an instance of Ruby's `::Logger` class/subclass;
|
141
141
|
# - at this moment the only debug logs are realised in 3 cases:
|
142
|
-
# - start of lock obtaining: "[redis_queud_locks.start_lock_obtaining] lock_key => 'rql:lock:your_lock'"
|
143
|
-
# - finish of the lock obtaining: "[redis_queued_locks.lock_obtained] lock_key => 'rql:lock:your_lock' acq_time => 123.456 (ms)"
|
144
|
-
# - start of the lock expiration after `yield`: "[redis_queud_locks.expire_lock] lock_key => 'rql:lock:your_lock'"
|
142
|
+
# - 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'"
|
143
|
+
# - 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)"
|
144
|
+
# - 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'"
|
145
145
|
# - by default uses VoidLogger that does nothing;
|
146
146
|
config.logger = RedisQueuedLocks::Logging::VoidLogger
|
147
147
|
|
148
148
|
# (default: false)
|
149
|
-
# - should be logged the each try
|
150
|
-
# -
|
149
|
+
# - should be logged the each internal try-retry lock acquire (a lot of logs can be generated depending on your retry configurations);
|
150
|
+
# - it adds 2 cases to the log in addition to the existing 3:
|
151
|
+
# - 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'"
|
152
|
+
# - 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'"
|
153
|
+
# - if logger is not configured this option does not lead to any effect;
|
151
154
|
config.log_lock_try = false
|
152
155
|
end
|
153
156
|
```
|
@@ -63,7 +63,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
63
63
|
rconn.multi(watch: [lock_key]) do |transact|
|
64
64
|
# Fast-Step X0: fail-fast check
|
65
65
|
if fail_fast && rconn.call('HGET', lock_key, 'acq_id')
|
66
|
-
# Fast-Step X1: is lock already obtained. fail fast
|
66
|
+
# Fast-Step X1: is lock already obtained. fail fast leads to "no try".
|
67
67
|
inter_result = :fail_fast_no_try
|
68
68
|
else
|
69
69
|
# Step 1: add an acquier to the lock acquirement queue
|
@@ -147,7 +147,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::TryToLock
|
|
147
147
|
'HSET',
|
148
148
|
lock_key,
|
149
149
|
'acq_id', acquier_id,
|
150
|
-
'ts', (timestamp = Time.now.
|
150
|
+
'ts', (timestamp = Time.now.to_f),
|
151
151
|
'ini_ttl', ttl
|
152
152
|
)
|
153
153
|
|
@@ -9,6 +9,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldWithExpire
|
|
9
9
|
# @param redis [RedisClient] Redis connection manager.
|
10
10
|
# @param logger [::Logger,#debug] Logger object.
|
11
11
|
# @param lock_key [String] Lock key to be expired.
|
12
|
+
# @param acquier_id [String] Acquier identifier.
|
12
13
|
# @param timed [Boolean] Should the lock be wrapped by Tiemlout with with lock's ttl
|
13
14
|
# @param ttl_shift [Float] Lock's TTL shifting. Should affect block's ttl. In millisecodns.
|
14
15
|
# @param ttl [Integer,NilClass] Lock's time to live (in ms). Nil means "without timeout".
|
@@ -17,7 +18,7 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldWithExpire
|
|
17
18
|
#
|
18
19
|
# @api private
|
19
20
|
# @since 0.1.0
|
20
|
-
def yield_with_expire(redis, logger, lock_key, timed, ttl_shift, ttl, &block)
|
21
|
+
def yield_with_expire(redis, logger, lock_key, acquier_id, timed, ttl_shift, ttl, &block)
|
21
22
|
if block_given?
|
22
23
|
if timed && ttl != nil
|
23
24
|
timeout = ((ttl - ttl_shift) / 1000.0).yield_self { |time| (time < 0) ? 0.0 : time }
|
@@ -28,7 +29,11 @@ module RedisQueuedLocks::Acquier::AcquireLock::YieldWithExpire
|
|
28
29
|
end
|
29
30
|
ensure
|
30
31
|
run_non_critical do
|
31
|
-
logger.debug(
|
32
|
+
logger.debug(
|
33
|
+
"[redis_queued_locks.expire_lock] " \
|
34
|
+
"lock_key => '#{lock_key}' " \
|
35
|
+
"acq_id => '#{acquier_id}'"
|
36
|
+
)
|
32
37
|
end
|
33
38
|
redis.call('EXPIRE', lock_key, '0')
|
34
39
|
end
|
@@ -176,7 +176,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
176
176
|
logger.debug(
|
177
177
|
"[redis_queued_locks.lock_obtained] " \
|
178
178
|
"lock_key => '#{result[:lock_key]}' " \
|
179
|
-
"acq_id
|
179
|
+
"acq_id => '#{acquier_id}' " \
|
180
180
|
"acq_time => #{acq_time} (ms)"
|
181
181
|
)
|
182
182
|
end
|
@@ -255,7 +255,7 @@ module RedisQueuedLocks::Acquier::AcquireLock
|
|
255
255
|
begin
|
256
256
|
yield_time = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
257
257
|
ttl_shift = ((yield_time - acq_process[:acq_end_time]) * 1000).ceil(2)
|
258
|
-
yield_with_expire(redis, logger, lock_key, timed, ttl_shift, ttl, &block)
|
258
|
+
yield_with_expire(redis, logger, lock_key, acquier_id, timed, ttl_shift, ttl, &block)
|
259
259
|
ensure
|
260
260
|
acq_process[:rel_time] = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
|
261
261
|
acq_process[:hold_time] = (
|
@@ -11,7 +11,7 @@ module RedisQueuedLocks::Acquier::LockInfo
|
|
11
11
|
# - result format: {
|
12
12
|
# lock_key: "rql:lock:your_lockname", # acquired lock key
|
13
13
|
# acq_id: "rql:acq:process_id/thread_id", # lock acquier identifier
|
14
|
-
# ts: 123456789, # <locked at> time stamp (epoch)
|
14
|
+
# ts: 123456789.2649841, # <locked at> time stamp (epoch, seconds.microseconds)
|
15
15
|
# ini_ttl: 123456789, # initial lock key ttl (milliseconds),
|
16
16
|
# rem_ttl: 123456789, # remaining lock key ttl (milliseconds)
|
17
17
|
# }
|
@@ -46,7 +46,7 @@ module RedisQueuedLocks::Acquier::LockInfo
|
|
46
46
|
{
|
47
47
|
lock_key: lock_key,
|
48
48
|
acq_id: hget_cmd_res['acq_id'],
|
49
|
-
ts:
|
49
|
+
ts: Float(hget_cmd_res['ts']),
|
50
50
|
ini_ttl: Integer(hget_cmd_res['ini_ttl']),
|
51
51
|
rem_ttl: ((pttl_cmd_res == -1) ? Infinity : pttl_cmd_res)
|
52
52
|
}
|
@@ -65,21 +65,21 @@ module RedisQueuedLocks::Resource
|
|
65
65
|
"rql:lock_queue:#{lock_name}"
|
66
66
|
end
|
67
67
|
|
68
|
-
# @return [
|
68
|
+
# @return [Float] Redis's <Set> score that is calculated from the time (epoch) as a float.
|
69
69
|
#
|
70
70
|
# @api private
|
71
71
|
# @since 0.1.0
|
72
72
|
def calc_initial_acquier_position
|
73
|
-
Time.now.
|
73
|
+
Time.now.to_f
|
74
74
|
end
|
75
75
|
|
76
76
|
# @param queue_ttl [Integer] In seconds
|
77
|
-
# @return [
|
77
|
+
# @return [Float] Redis's <Set> score barrier for acquiers that should be removed from queue.
|
78
78
|
#
|
79
79
|
# @api private
|
80
80
|
# @since 0.1.0
|
81
81
|
def acquier_dead_score(queue_ttl)
|
82
|
-
Time.now.
|
82
|
+
Time.now.to_f - queue_ttl
|
83
83
|
end
|
84
84
|
|
85
85
|
# @param lock_queue [String]
|