redlock 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MWU3MmRhNjM0OWFkYTMyOTMzNzBiNDFjYjFmZDkwOGRhNGFkMzgzMQ==
5
- data.tar.gz: !binary |-
6
- M2EyYWE0YTk5NTg3MThiZWIzNjA2OGRhMjE3MzY1ZjBmMmU2OTI2Zg==
2
+ SHA1:
3
+ metadata.gz: edd7557c70328ce28bfb2449afcbfbea7a0b12a2
4
+ data.tar.gz: eca5ea4f4e71cf7013d43541fbfb43af4edfb1d6
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MDI3YjUyYjQxOTJmNzAyZTE5MGY3MjlhNWYyMjVmZDE4YWQ1YTRkMDA0ODcw
10
- M2RlYmQ0NTA3NGUwZjdlYWM0MjM1MjFiNjY4N2YwMzkwM2I5M2MxZjM5OWVi
11
- YzdlYzVmOTBlOTRkNzRhNjNhYjNhYzU0OGU1ZTJhNzg0NjUxMjQ=
12
- data.tar.gz: !binary |-
13
- MDFmYTU0MjRhZWFhOGY2NTM5YmM4NmQ2ZTA2MDI5NzQ1NjVlZjc2ODhhM2Nm
14
- N2JkNmJlZTI5ODU3NzM3MmIxZjUxY2M5ZmZhOTNiOThiNzdmOGI1Zjc2ZTI3
15
- ZDkxZGExNTBkY2Y3MGMyMmU0M2U4MmM4OWE5MWZhNTM5Mjg5ODQ=
6
+ metadata.gz: 1a97dfd84d0edf67f270332364593f52f8b679f88f4491f3291be115bf7571383f096a45c9fd04a81b46708057ca4c1f59ae50bd3dcc0e0842bdffa7b18e0238
7
+ data.tar.gz: f45f4b8436fc3d9141c8ed209627818fb1eaa082e95fbde6bdb9358463898b42103d0260920fa081edf743428caa050bfdbe4f81f02f026b68e7008db9b9b899
@@ -4,3 +4,5 @@ services:
4
4
  rvm:
5
5
  - "2.0.0"
6
6
  script: bundle exec rspec spec
7
+ sudo: false
8
+ cache: bundler
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redlock (0.1.2)
4
+ redlock (0.1.4)
5
5
  redis (~> 3, >= 3.0.5)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -86,7 +86,7 @@ begin
86
86
  block_result = lock_manager.lock!("resource_key", 2000) do
87
87
  # critical code
88
88
  end
89
- rescue Redlock::LockException
89
+ rescue Redlock::LockError
90
90
  # error handling
91
91
  end
92
92
  ```
@@ -102,11 +102,15 @@ module Redlock
102
102
  end
103
103
 
104
104
  def lock(resource, val, ttl)
105
- @redis.evalsha(@lock_script_sha, keys: [resource], argv: [val, ttl])
105
+ recover_from_script_flush do
106
+ @redis.evalsha @lock_script_sha, keys: [resource], argv: [val, ttl]
107
+ end
106
108
  end
107
109
 
108
110
  def unlock(resource, val)
109
- @redis.evalsha(@unlock_script_sha, keys: [resource], argv: [val])
111
+ recover_from_script_flush do
112
+ @redis.evalsha @unlock_script_sha, keys: [resource], argv: [val]
113
+ end
110
114
  rescue
111
115
  # Nothing to do, unlocking is just a best-effort attempt.
112
116
  end
@@ -117,6 +121,24 @@ module Redlock
117
121
  @unlock_script_sha = @redis.script(:load, UNLOCK_SCRIPT)
118
122
  @lock_script_sha = @redis.script(:load, LOCK_SCRIPT)
119
123
  end
124
+
125
+ def recover_from_script_flush
126
+ retry_on_noscript = true
127
+ begin
128
+ yield
129
+ rescue Redis::CommandError => e
130
+ # When somebody has flushed the Redis instance's script cache, we might
131
+ # want to reload our scripts. Only attempt this once, though, to avoid
132
+ # going into an infinite loop.
133
+ if retry_on_noscript && e.message.include?('NOSCRIPT')
134
+ load_scripts
135
+ retry_on_noscript = false
136
+ retry
137
+ else
138
+ raise
139
+ end
140
+ end
141
+ end
120
142
  end
121
143
 
122
144
  def try_lock_instances(resource, ttl, extend)
@@ -1,3 +1,3 @@
1
1
  module Redlock
2
- VERSION = "0.1.3"
2
+ VERSION = '0.1.4'
3
3
  end
@@ -73,6 +73,43 @@ RSpec.describe Redlock::Client do
73
73
  end
74
74
  end
75
75
 
76
+ context 'when script cache has been flushed' do
77
+ before(:each) do
78
+ @manipulated_instance = lock_manager.instance_variable_get(:@servers).first
79
+ @manipulated_instance.instance_variable_get(:@redis).script(:flush)
80
+ end
81
+
82
+ it 'does not raise a Redis::CommandError: NOSCRIPT error' do
83
+ expect {
84
+ lock_manager.lock(resource_key, ttl)
85
+ }.to_not raise_error
86
+ end
87
+
88
+ it 'tries to load the scripts to cache again' do
89
+ expect(@manipulated_instance).to receive(:load_scripts).and_call_original
90
+ lock_manager.lock(resource_key, ttl)
91
+ end
92
+
93
+ context 'when the script re-loading fails' do
94
+ it 'does not try to to load the scripts to cache again twice' do
95
+ # This time we do not pass it through to Redis, in order to simulate a passing
96
+ # call to LOAD SCRIPT followed by another NOSCRIPT error. Imagine someone
97
+ # repeatedly calling SCRIPT FLUSH on our Redis instance.
98
+ expect(@manipulated_instance).to receive(:load_scripts)
99
+
100
+ expect {
101
+ lock_manager.lock(resource_key, ttl)
102
+ }.to raise_error(/NOSCRIPT/)
103
+ end
104
+ end
105
+
106
+ context 'when the script re-loading succeeds' do
107
+ it 'locks' do
108
+ expect(lock_manager.lock(resource_key, ttl)).to be_lock_info_for(resource_key)
109
+ end
110
+ end
111
+ end
112
+
76
113
  describe 'block syntax' do
77
114
  context 'when lock is available' do
78
115
  it 'locks' do
metadata CHANGED
@@ -1,89 +1,89 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redlock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Moreira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-09 00:00:00.000000000 Z
11
+ date: 2015-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3'
20
- - - ! '>='
20
+ - - ">="
21
21
  - !ruby/object:Gem::Version
22
22
  version: 3.0.5
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
- - - ~>
27
+ - - "~>"
28
28
  - !ruby/object:Gem::Version
29
29
  version: '3'
30
- - - ! '>='
30
+ - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 3.0.5
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: bundler
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ~>
37
+ - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: '1.7'
40
40
  type: :development
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
- - - ~>
44
+ - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '1.7'
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: coveralls
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ! '>='
51
+ - - ">="
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ! '>='
58
+ - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: rake
63
63
  requirement: !ruby/object:Gem::Requirement
64
64
  requirements:
65
- - - ~>
65
+ - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: '10.0'
68
68
  type: :development
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
- - - ~>
72
+ - - "~>"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '10.0'
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: rspec
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - ~>
79
+ - - "~>"
80
80
  - !ruby/object:Gem::Version
81
81
  version: '3.1'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - ~>
86
+ - - "~>"
87
87
  - !ruby/object:Gem::Version
88
88
  version: '3.1'
89
89
  description: Distributed lock using Redis written in Ruby. Highly inspired by https://github.com/antirez/redlock-rb.
@@ -93,9 +93,9 @@ executables: []
93
93
  extensions: []
94
94
  extra_rdoc_files: []
95
95
  files:
96
- - .gitignore
97
- - .rspec
98
- - .travis.yml
96
+ - ".gitignore"
97
+ - ".rspec"
98
+ - ".travis.yml"
99
99
  - CONTRIBUTORS
100
100
  - Gemfile
101
101
  - Gemfile.lock
@@ -120,17 +120,17 @@ require_paths:
120
120
  - lib
121
121
  required_ruby_version: !ruby/object:Gem::Requirement
122
122
  requirements:
123
- - - ! '>='
123
+ - - ">="
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
126
  required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  requirements:
128
- - - ! '>='
128
+ - - ">="
129
129
  - !ruby/object:Gem::Version
130
130
  version: '0'
131
131
  requirements: []
132
132
  rubyforge_project:
133
- rubygems_version: 2.4.6
133
+ rubygems_version: 2.2.2
134
134
  signing_key:
135
135
  specification_version: 4
136
136
  summary: Distributed lock using Redis written in Ruby.
@@ -138,3 +138,4 @@ test_files:
138
138
  - spec/client_spec.rb
139
139
  - spec/spec_helper.rb
140
140
  - spec/testing_spec.rb
141
+ has_rdoc: