redis_mutex 0.0.1 → 0.0.2.alpha.12
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 +13 -5
- data/lib/redis_mutex/version.rb +1 -1
- data/lib/redis_mutex.rb +41 -28
- data/redis_mutex.gemspec +2 -1
- data/test/test_redis_mutex.rb +11 -2
- metadata +16 -16
checksums.yaml
CHANGED
@@ -1,7 +1,15 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MmNmNTU4ZmRlOWM4MDBiYTIyNDdlYjUzYTBmZjA1OTE4N2E1MjQ2ZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZTYzZDg3NjdmNzc2ZDEyZDNmYjU4MWJiMzM1MzBmZTQwYTVhM2M5Yg==
|
5
7
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ZGRkMTZjZjYzMThmYTQxMTJiMjExNjc0MjcxYzQzYWYwNDRmZmQwY2JmNTA4
|
10
|
+
NjBmMGMzNzY4MjlmNmFhZGFlZjhhZDY4YjhkMjBjMjlmZGNjZDE1YmMxYWZm
|
11
|
+
ODFkODk3ZDBlM2ZiOWUxMWE1MDFlMDQyOGI1NjIwODJkYTYyY2Q=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NzhjNDY1YTZmYTFiMzkzNzYzMGU5YjMwYWRkZTM3NmRlNmU2OTI4MDMwMTg4
|
14
|
+
NjVlMGYwOWYzYzMxNjNkMmY3ZmMwMjQxYTNhNjllNjAyYjgzODUxOTdkZTM1
|
15
|
+
N2RjMGE5MWM1NzRjNmM4YTNkMWI0OTExZjMxODI2ODZhNTAwNjQ=
|
data/lib/redis_mutex/version.rb
CHANGED
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/redis_mutex.gemspec
CHANGED
@@ -6,7 +6,7 @@ require 'redis_mutex/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "redis_mutex"
|
8
8
|
if ENV['TRAVIS']
|
9
|
-
spec.version = "#{RedisMutex::VERSION}
|
9
|
+
spec.version = "#{RedisMutex::VERSION}.alpha.#{ENV['TRAVIS_BUILD_NUMBER']}"
|
10
10
|
else
|
11
11
|
spec.version = RedisMutex::VERSION
|
12
12
|
end
|
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.description = %q{}
|
17
17
|
spec.homepage = "https://github.com/GoodGuide/redis_mutex"
|
18
18
|
spec.license = "MIT"
|
19
|
+
spec.required_ruby_version = '>= 1.9.3'
|
19
20
|
|
20
21
|
spec.files = `git ls-files -z`.split("\x0")
|
21
22
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
data/test/test_redis_mutex.rb
CHANGED
@@ -43,11 +43,11 @@ class TestRedisMutex < Minitest::Test
|
|
43
43
|
assert redis.get(key) == original_token
|
44
44
|
end
|
45
45
|
|
46
|
-
def
|
46
|
+
def test_locked_is_false_when_unlocked
|
47
47
|
assert !mutex_a.locked?
|
48
48
|
end
|
49
49
|
|
50
|
-
def
|
50
|
+
def test_locked_is_true_when_locked
|
51
51
|
mutex_a.acquire_lock(DEFAULT_TIMEOUT)
|
52
52
|
assert mutex_a.locked?
|
53
53
|
end
|
@@ -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
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_mutex
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2.alpha.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Taylor Long
|
@@ -14,56 +14,56 @@ dependencies:
|
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.7'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.7'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '10.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ~>
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '10.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ~>
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 5.5.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 5.5.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: redis
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ~>
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: 3.2.0
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ~>
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 3.2.0
|
69
69
|
description: ''
|
@@ -73,8 +73,8 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
-
-
|
77
|
-
-
|
76
|
+
- .gitignore
|
77
|
+
- .travis.yml
|
78
78
|
- Gemfile
|
79
79
|
- Guardfile
|
80
80
|
- LICENSE.txt
|
@@ -94,17 +94,17 @@ require_paths:
|
|
94
94
|
- lib
|
95
95
|
required_ruby_version: !ruby/object:Gem::Requirement
|
96
96
|
requirements:
|
97
|
-
- -
|
97
|
+
- - ! '>='
|
98
98
|
- !ruby/object:Gem::Version
|
99
|
-
version:
|
99
|
+
version: 1.9.3
|
100
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
101
|
requirements:
|
102
|
-
- -
|
102
|
+
- - ! '>'
|
103
103
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
104
|
+
version: 1.3.1
|
105
105
|
requirements: []
|
106
106
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.
|
107
|
+
rubygems_version: 2.4.5
|
108
108
|
signing_key:
|
109
109
|
specification_version: 4
|
110
110
|
summary: Simple distributed mutex using Redis.
|