redis_mutex 0.0.1.pre.alpha.pre.10 → 0.0.1.pre.alpha.pre.11
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 +8 -8
- data/lib/redis_mutex.rb +41 -28
- data/test/test_redis_mutex.rb +9 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZWU4ZmJkOTliYzc4MzFlMDY3ZmE1ZTdjZThjNzM3OTEzNmQ1YTQ0OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTBlYmMxZjA5YzcxMjQ0N2Q3NDBjYzUwMjRlOWZiMjM4OTVkOGEyNA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
OTRmYWNkY2M3Yjk1ZWRjZjFhMTIwNDA2ODdlODQ4YzQ4ODdiODAwZDcxNjlh
|
10
|
+
ZGU4OGNjYjc0MWU3YTIwYTRhMGQxMmQzOThmZWRjM2Y2MzFkYTI1ZmM5NDM4
|
11
|
+
NDUyODA3MmJjNTczNjZjOWNiZTA5M2Q3MTQ3NTc3ZDE5YmFkNTE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MzcyZmQ0MTE0MzlmOWYxZTI3NjU1NzkxZjZjNjA4Zjk3NjgxNjQ2NzgyZThk
|
14
|
+
YzBlMWI4NDM1YWQ0MjMxZWQ1ODBiMTA4ZGVhOGFmODkwYmUxZWUyZjAxZmMz
|
15
|
+
ZGU3ZDAxZTJiNTNlYzUwZDM1OTc4OWVhZDYyY2NkY2M1OTk3NGY=
|
data/lib/redis_mutex.rb
CHANGED
@@ -2,9 +2,16 @@ require "redis_mutex/version"
|
|
2
2
|
require 'securerandom'
|
3
3
|
|
4
4
|
class RedisMutex
|
5
|
-
|
5
|
+
SCRIPTS = {}
|
6
6
|
MutexNotLockedError = Class.new(StandardError)
|
7
7
|
|
8
|
+
def self.def_redis_script(name, source)
|
9
|
+
SCRIPTS[name] = {
|
10
|
+
source: source,
|
11
|
+
sha: Digest::SHA1.hexdigest(source),
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
8
15
|
def initialize(redis, name, token=nil)
|
9
16
|
@redis = redis
|
10
17
|
@name = name
|
@@ -22,40 +29,37 @@ class RedisMutex
|
|
22
29
|
@redis.set(key, token, nx: true, ex: expire)
|
23
30
|
end
|
24
31
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
return redis.call('del', KEYS[1])
|
32
|
-
LUA
|
32
|
+
def_redis_script :compare_and_delete, <<-LUA
|
33
|
+
if ARGV[1] ~= redis.call('get', KEYS[1]) then
|
34
|
+
return false
|
35
|
+
end
|
33
36
|
|
34
|
-
|
37
|
+
return redis.call('del', KEYS[1])
|
38
|
+
LUA
|
39
|
+
def release
|
40
|
+
run_script(:compare_and_delete, [key], [token]) or raise MutexNotLockedError
|
35
41
|
end
|
36
42
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
return redis.call('expire', KEYS[1], ARGV[2])
|
44
|
-
LUA
|
43
|
+
def_redis_script :compare_and_expire, <<-LUA
|
44
|
+
if ARGV[1] ~= redis.call('get', KEYS[1]) then
|
45
|
+
return false
|
46
|
+
end
|
45
47
|
|
46
|
-
|
48
|
+
return redis.call('expire', KEYS[1], ARGV[2])
|
49
|
+
LUA
|
50
|
+
def renew(expire)
|
51
|
+
run_script(:compare_and_expire, [key], [token, expire]) or raise MutexNotLockedError
|
47
52
|
end
|
48
53
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
return redis.call('set', KEYS[1], ARGV[2])
|
56
|
-
LUA
|
54
|
+
def_redis_script :compare_and_swap, <<-LUA
|
55
|
+
if ARGV[1] ~= redis.call('get', KEYS[1]) then
|
56
|
+
return false
|
57
|
+
end
|
57
58
|
|
58
|
-
|
59
|
+
return redis.call('set', KEYS[1], ARGV[2])
|
60
|
+
LUA
|
61
|
+
def set_token(new_token)
|
62
|
+
run_script(:compare_and_swap, [key], [token, new_token]) or raise MutexNotLockedError
|
59
63
|
@token = new_token
|
60
64
|
end
|
61
65
|
|
@@ -66,4 +70,13 @@ class RedisMutex
|
|
66
70
|
def verify!
|
67
71
|
locked? or raise MutexNotLockedError
|
68
72
|
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def run_script(name, keys, args)
|
77
|
+
script = SCRIPTS.fetch(name)
|
78
|
+
@redis.evalsha(script.fetch(:sha), keys, args)
|
79
|
+
rescue Redis::CommandError
|
80
|
+
@redis.eval(script.fetch(:source), keys, args)
|
81
|
+
end
|
69
82
|
end
|
data/test/test_redis_mutex.rb
CHANGED
@@ -117,4 +117,13 @@ class TestRedisMutex < Minitest::Test
|
|
117
117
|
assert RedisMutex.new(redis, mutex_name, mutex_a.token).release
|
118
118
|
end
|
119
119
|
|
120
|
+
def test_automatic_script_loading
|
121
|
+
# lock to ensure a script is loaded and its SHA cached
|
122
|
+
mutex_a.acquire_lock(1)
|
123
|
+
mutex_a.release
|
124
|
+
|
125
|
+
redis.script(:flush)
|
126
|
+
assert mutex_a.acquire_lock(1)
|
127
|
+
end
|
128
|
+
|
120
129
|
end
|