redlock 0.1.3 → 0.1.4

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 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: