redlock 0.1.6 → 0.1.7

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,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2ea5ebfa119462a5500c078e0f113480b0178429
4
- data.tar.gz: aad002651ed21a7782d63794f7d4cb9073e529e9
3
+ metadata.gz: 86073e680a1deb905852ddfcd28042cf81729875
4
+ data.tar.gz: 76cffc3d01b4fa649ad4ae4276149453282c0ed4
5
5
  SHA512:
6
- metadata.gz: b099d48798f351476f7a225a924c6a0c2671b4ef25aad314f573b152a5ca587d43fdb2b29ca4fc6dc1031e9dc6060c99dace1f96eb06b57a47dc544a2df20901
7
- data.tar.gz: ac4a7b903e6913e691f99b536cd31462a2da41fe14cfa23fd30665b35bae78d9a8da1e2495721f9aa53b6bcb44fc922423e86cf56cf14bec5f82ef9e38698351
6
+ metadata.gz: 8b0687bd912eff82bb3f4607de313d681d1e18971cbd3b6b484bae0fabae38b258ef423f0c00256b45e633fbc83abea9b38c57fbf08ce4d6567a2c254701eeb7
7
+ data.tar.gz: 86dc485ebc704b9d46bd6878d18f9b7403c13840721a2475b4b61b5c7b4099a40db3375045df8c8be7e9270d52f9560854b489a3656805046d995e253b1d126b
data/.travis.yml CHANGED
@@ -2,7 +2,7 @@ language: ruby
2
2
  services:
3
3
  - redis-server
4
4
  rvm:
5
- - "2.0.0"
5
+ - "2.2.2"
6
6
  script: bundle exec rspec spec
7
7
  sudo: false
8
8
  cache: bundler
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redlock (0.1.6)
4
+ redlock (0.1.7)
5
5
  redis (~> 3, >= 3.3.0)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -95,6 +95,22 @@ rescue Redlock::LockError
95
95
  end
96
96
  ```
97
97
 
98
+ To extend the life of the lock, provided that you didn't let it expire:
99
+
100
+ ```ruby
101
+ begin
102
+ block_result = lock_manager.lock!("resource_key", 2000) do |lock_info|
103
+ # critical code
104
+ lock_manager.extend_life!(lock_info, 3000)
105
+ # more critical code
106
+ end
107
+ rescue Redlock::LockError
108
+ # error handling
109
+ end
110
+ ```
111
+ There's also a non-bang version that returns true when the lock was
112
+ extended
113
+
98
114
  ## Run tests
99
115
 
100
116
  Make sure you have at least 1 redis instances up.
@@ -52,6 +52,30 @@ module Redlock
52
52
  end
53
53
  end
54
54
 
55
+ def extend_life(to_extend, ttl)
56
+ value = to_extend.fetch(:value)
57
+ resource = to_extend.fetch(:resource)
58
+
59
+
60
+ extended, time_elapsed = timed do
61
+ @servers.all? { |s| s.extend_life(resource, value, ttl) }
62
+ end
63
+
64
+ validity = ttl - time_elapsed - drift(ttl)
65
+
66
+ if extended
67
+ { validity: validity, resource: resource, value: value }
68
+ else
69
+ @servers.each { |s| s.unlock(resource, value) }
70
+ false
71
+ end
72
+ end
73
+
74
+ def extend_life!(to_extend, ttl)
75
+ new_lock_info = self.extend_life(to_extend, ttl)
76
+ raise LockError, 'failed to extend lock' unless new_lock_info
77
+ end
78
+
55
79
  # Unlocks a resource.
56
80
  # Params:
57
81
  # +lock_info+:: the lock that has been acquired when you locked the resource.
@@ -91,6 +115,16 @@ module Redlock
91
115
  end
92
116
  eos
93
117
 
118
+ EXTEND_LOCK_SCRIPT = <<-eos
119
+ if redis.call("get", KEYS[1]) == ARGV[1] then
120
+ redis.call("expire", KEYS[1], ARGV[2])
121
+ return 0
122
+ else
123
+ return 1
124
+ end
125
+ eos
126
+
127
+
94
128
  def initialize(connection)
95
129
  if connection.respond_to?(:client)
96
130
  @redis = connection
@@ -107,6 +141,13 @@ module Redlock
107
141
  end
108
142
  end
109
143
 
144
+ def extend_life(resource, val, ttl)
145
+ recover_from_script_flush do
146
+ rc = @redis.evalsha @extend_lock_script_sha, keys: [resource], argv: [val, ttl]
147
+ rc == 0
148
+ end
149
+ end
150
+
110
151
  def unlock(resource, val)
111
152
  recover_from_script_flush do
112
153
  @redis.evalsha @unlock_script_sha, keys: [resource], argv: [val]
@@ -120,6 +161,7 @@ module Redlock
120
161
  def load_scripts
121
162
  @unlock_script_sha = @redis.script(:load, UNLOCK_SCRIPT)
122
163
  @lock_script_sha = @redis.script(:load, LOCK_SCRIPT)
164
+ @extend_lock_script_sha = @redis.script(:load, EXTEND_LOCK_SCRIPT)
123
165
  end
124
166
 
125
167
  def recover_from_script_flush
@@ -1,3 +1,3 @@
1
1
  module Redlock
2
- VERSION = '0.1.6'
2
+ VERSION = '0.1.7'
3
3
  end
data/spec/client_spec.rb CHANGED
@@ -170,6 +170,40 @@ RSpec.describe Redlock::Client do
170
170
  end
171
171
  end
172
172
 
173
+ describe "extend" do
174
+ context 'when lock is available' do
175
+ before { @lock_info = lock_manager.lock(resource_key, ttl) }
176
+ after(:each) { lock_manager.unlock(@lock_info) if @lock_info }
177
+
178
+ it 'can extend its own lock' do
179
+ lock_info = lock_manager.extend_life(@lock_info, ttl)
180
+ expect(lock_info).to be_lock_info_for(resource_key)
181
+ end
182
+
183
+ it "can't extend a nonexistent lock" do
184
+ lock_manager.unlock(@lock_info)
185
+ lock_info = lock_manager.extend_life(@lock_info, ttl)
186
+ expect(lock_info).to eq(false)
187
+ end
188
+ end
189
+ end
190
+
191
+ describe "extend!" do
192
+ context 'when lock is available' do
193
+ before { @lock_info = lock_manager.lock(resource_key, ttl) }
194
+ after(:each) { lock_manager.unlock(@lock_info) if @lock_info }
195
+
196
+ it 'can extend its own lock' do
197
+ expect{ lock_manager.extend_life!(@lock_info, ttl) }.to_not raise_error
198
+ end
199
+
200
+ it "can't extend a nonexistent lock" do
201
+ lock_manager.unlock(@lock_info)
202
+ expect{ lock_manager.extend_life!(@lock_info, ttl) }.to raise_error(Redlock::LockError)
203
+ end
204
+ end
205
+ end
206
+
173
207
  describe 'lock!' do
174
208
  context 'when lock is available' do
175
209
  it 'locks' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redlock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Moreira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-12 00:00:00.000000000 Z
11
+ date: 2016-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis