redis_getlock 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +3 -1
- data/bin/try +1 -1
- data/lib/redis_getlock/version.rb +1 -1
- data/lib/redis_getlock.rb +20 -19
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9c0826498386afb3440ad4c10e7ce2b984a6eac2
|
4
|
+
data.tar.gz: f52a7bc3a8d04316bb3985025ca859b4f703885b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5a15c9c815fb0c2a7b8fe586bbe5985b17aab40b8f0193a9098e5345e396ec1b440e7776c3e6eec9230296304130b748b5f2f8a4560c44a42f4b8f5c037faec
|
7
|
+
data.tar.gz: 950bcb6a8643fdb4470c9963389d11bbe2c9d275bb53567f997ad25787619396474025ca4c9a4a95a20dae51db718b35833d636162c5056ada289ac110d02f1e
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -77,11 +77,13 @@ Similarly with ruby standard library [mutex](https://ruby-doc.org/core-2.2.0/Mut
|
|
77
77
|
* lock
|
78
78
|
* Attempts to grab the lock and waits if it isn’t available.
|
79
79
|
* locked?
|
80
|
-
* Returns true if this lock is currently held by some.
|
80
|
+
* Returns true if this lock is currently held by some (including myself).
|
81
81
|
* synchronize {}
|
82
82
|
* Obtains a lock, runs the block, and releases the lock when the block completes.
|
83
83
|
* unlock
|
84
84
|
* Releases the lock.
|
85
|
+
* self_locked?
|
86
|
+
* Returns true if this lock is currently held by myself.
|
85
87
|
|
86
88
|
Options of `RedisGetlock.new` are:
|
87
89
|
|
data/bin/try
CHANGED
@@ -14,7 +14,7 @@ mutex = RedisGetlock.new(redis: Redis.new, key: 'redis_getlock', logger: Logger.
|
|
14
14
|
puts 'redis-cli> del redis_getlock'
|
15
15
|
mutex.synchronize do
|
16
16
|
loop do
|
17
|
-
puts mutex.locked?
|
17
|
+
puts "locked?:#{mutex.locked?} self_locked?:#{mutex.self_locked?}"
|
18
18
|
sleep 1
|
19
19
|
end
|
20
20
|
end
|
data/lib/redis_getlock.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'redis'
|
2
2
|
require "redis_getlock/version"
|
3
3
|
require 'securerandom'
|
4
|
+
require 'json'
|
4
5
|
|
5
6
|
class RedisGetlock
|
6
|
-
attr_reader :redis, :key, :logger, :expire, :interval
|
7
|
+
attr_reader :redis, :key, :logger, :expire, :interval, :uuid
|
7
8
|
|
8
9
|
EXPIRE = 2
|
9
10
|
INTERVAL = 1
|
@@ -14,17 +15,17 @@ class RedisGetlock
|
|
14
15
|
@logger = logger
|
15
16
|
@expire = expire
|
16
17
|
@interval = interval
|
18
|
+
@uuid = SecureRandom.uuid
|
17
19
|
end
|
18
20
|
|
19
21
|
def lock
|
20
22
|
logger.info { "#{log_head}Wait acquiring a redis lock '#{key}'" } if logger
|
21
23
|
if set_options_available?
|
22
24
|
lock_with_set_options
|
23
|
-
@thr = Thread.new(&method(:keeplock_with_set_options))
|
24
25
|
else
|
25
26
|
lock_without_set_options
|
26
|
-
@thr = Thread.new(&method(:keeplock_without_set_options))
|
27
27
|
end
|
28
|
+
@thr = Thread.new(&method(:keeplock))
|
28
29
|
logger.info { "#{log_head}Acquired a redis lock '#{key}'" } if logger
|
29
30
|
end
|
30
31
|
|
@@ -38,6 +39,10 @@ class RedisGetlock
|
|
38
39
|
redis.exists(key)
|
39
40
|
end
|
40
41
|
|
42
|
+
def self_locked?
|
43
|
+
redis.exists(key) && uuid == JSON.parse(redis.get(key))['uuid']
|
44
|
+
end
|
45
|
+
|
41
46
|
def synchronize(&block)
|
42
47
|
lock
|
43
48
|
begin
|
@@ -62,16 +67,10 @@ class RedisGetlock
|
|
62
67
|
# redis >= 2.6.12
|
63
68
|
# ref. http://redis.io/commands/set
|
64
69
|
def lock_with_set_options
|
65
|
-
uuid = SecureRandom.uuid
|
66
|
-
loop do
|
67
|
-
break if redis.set(key, uuid, {nx: true, ex: expire}) # key does not exist
|
68
|
-
sleep interval
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def keeplock_with_set_options
|
73
70
|
loop do
|
74
|
-
|
71
|
+
current = Time.now.to_f
|
72
|
+
payload = {uuid: uuid, expire_at: (current + expire).to_s}.to_json
|
73
|
+
break if redis.set(key, payload, {nx: true, ex: expire}) # key does not exist
|
75
74
|
sleep interval
|
76
75
|
end
|
77
76
|
end
|
@@ -81,23 +80,25 @@ class RedisGetlock
|
|
81
80
|
def lock_without_set_options
|
82
81
|
loop do
|
83
82
|
current = Time.now.to_f
|
84
|
-
|
83
|
+
payload = {uuid: uuid, expire_at: (current + expire).to_s}.to_json
|
84
|
+
if redis.setnx(key, payload) # key does not exist
|
85
85
|
redis.expire(key, expire)
|
86
86
|
break # acquire lock
|
87
87
|
end
|
88
|
-
|
89
|
-
if
|
90
|
-
compared = redis.getset(key,
|
91
|
-
break if
|
88
|
+
previous = JSON.parse(redis.get(key))
|
89
|
+
if previous['expire_at'].to_f < current # key exists, but previous
|
90
|
+
compared = redis.getset(key, paylod)
|
91
|
+
break if previous['expire_at'] == compared['expire_at'] # acquire lock
|
92
92
|
end
|
93
93
|
sleep interval
|
94
94
|
end
|
95
95
|
end
|
96
96
|
|
97
|
-
def
|
97
|
+
def keeplock
|
98
98
|
loop do
|
99
99
|
current = Time.now.to_f
|
100
|
-
|
100
|
+
payload = {uuid: uuid, expire_at: (current + expire).to_s}.to_json
|
101
|
+
redis.setex(key, expire, payload) # extend expiration
|
101
102
|
sleep interval
|
102
103
|
end
|
103
104
|
end
|