redis_mutex 0.0.1 → 0.0.2.alpha.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: ed7285292327df555cdb24c880c95488bd49ef48
4
- data.tar.gz: f664b54f0fcc52e1e1d90e771c52666f18174063
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MmNmNTU4ZmRlOWM4MDBiYTIyNDdlYjUzYTBmZjA1OTE4N2E1MjQ2ZQ==
5
+ data.tar.gz: !binary |-
6
+ ZTYzZDg3NjdmNzc2ZDEyZDNmYjU4MWJiMzM1MzBmZTQwYTVhM2M5Yg==
5
7
  SHA512:
6
- metadata.gz: 4a0177cb03328bcca09855fbc2abeab8eeb9ef26785eee204bd7ce2cc2325a90c878015efabcd17709c4644dbb8582b12873289ae069da9d48a421da0f350fbb
7
- data.tar.gz: 4c3eaff96de53af183942973176a2055b2efbae2aeda1393120ea6d4d97787d20b70ba87988bc562ee50ca0c4d2c515b8a834a2e419dccf8229f2434ed31d13c
8
+ metadata.gz: !binary |-
9
+ ZGRkMTZjZjYzMThmYTQxMTJiMjExNjc0MjcxYzQzYWYwNDRmZmQwY2JmNTA4
10
+ NjBmMGMzNzY4MjlmNmFhZGFlZjhhZDY4YjhkMjBjMjlmZGNjZDE1YmMxYWZm
11
+ ODFkODk3ZDBlM2ZiOWUxMWE1MDFlMDQyOGI1NjIwODJkYTYyY2Q=
12
+ data.tar.gz: !binary |-
13
+ NzhjNDY1YTZmYTFiMzkzNzYzMGU5YjMwYWRkZTM3NmRlNmU2OTI4MDMwMTg4
14
+ NjVlMGYwOWYzYzMxNjNkMmY3ZmMwMjQxYTNhNjllNjAyYjgzODUxOTdkZTM1
15
+ N2RjMGE5MWM1NzRjNmM4YTNkMWI0OTExZjMxODI2ODZhNTAwNjQ=
@@ -1,3 +1,3 @@
1
1
  class RedisMutex
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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
- SHAs = {}
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
- def release
26
- sha = SHAs[:delete_if_locked] ||= @redis.script(:load, <<-LUA)
27
- if ARGV[1] ~= redis.call('get', KEYS[1]) then
28
- return false
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
- @redis.evalsha(sha, [key], [token]) or raise MutexNotLockedError
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
- def renew(expire)
38
- sha = SHAs[:set_expiration_if_locked] ||= @redis.script(:load, <<-LUA)
39
- if ARGV[1] ~= redis.call('get', KEYS[1]) then
40
- return false
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
- @redis.evalsha(sha, [key], [token, expire]) or raise MutexNotLockedError
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
- def set_token(new_token)
50
- sha = SHAs[:compare_and_swap] ||= @redis.script(:load, <<-LUA)
51
- if ARGV[1] ~= redis.call('get', KEYS[1]) then
52
- return false
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
- @redis.evalsha(sha, [key], [token, new_token]) or raise MutexNotLockedError
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}-alpha-#{ENV['TRAVIS_BUILD_NUMBER']}"
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) }
@@ -43,11 +43,11 @@ class TestRedisMutex < Minitest::Test
43
43
  assert redis.get(key) == original_token
44
44
  end
45
45
 
46
- def test_locked_when_unlocked
46
+ def test_locked_is_false_when_unlocked
47
47
  assert !mutex_a.locked?
48
48
  end
49
49
 
50
- def test_locked_when_locked
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.1
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
- - ".gitignore"
77
- - ".travis.yml"
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: '0'
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: '0'
104
+ version: 1.3.1
105
105
  requirements: []
106
106
  rubyforge_project:
107
- rubygems_version: 2.2.2
107
+ rubygems_version: 2.4.5
108
108
  signing_key:
109
109
  specification_version: 4
110
110
  summary: Simple distributed mutex using Redis.