robust-redis-lock 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9fa5c673571893a2695d8a6b4938a0244c1014ba
4
- data.tar.gz: da55dd270b522b7a845cf54d999d854efda7352d
3
+ metadata.gz: 23f3a1cbf8593c30a609665262248cc8359727ba
4
+ data.tar.gz: 3aff7aaaca003505cf84213eef01421ab98eef32
5
5
  SHA512:
6
- metadata.gz: 279699f922fe00b4b72428878a044edb0fcb9a411bbb141688ff2d53c6bc1596ce5da6127a41108474064bb2217bcd11081bd2ea12faff97f83ab1c549deb91f
7
- data.tar.gz: 2d9e74e71ca98ebcd1f18a274f109b5d51b0bfd1ffebcf207bbb9c20264831041191dfb28d87e205110347ad06e243b43591b8d81f7f1de4ac1084b4fa0bff89
6
+ metadata.gz: ceb8ffe2f1b2885cae20a2c586e82fc1e1fd9e4ba2956cf50b024f62a51ade42f6649a419924fe8f12c2d48d2aa4c1447c1f096294754c70acbc6e35ad1ed3d3
7
+ data.tar.gz: 62a08c7e3bdd4ce2b765128f79d71ee2d70df13120a70cc554102492770ef647dcefe05807329458f17121d61c8853fc6aa12607fd4ff43bce774cc21501239c
@@ -19,7 +19,20 @@ class Redis::Lock
19
19
  redis = options[:redis] || self.redis
20
20
  raise "redis cannot be nil" if redis.nil?
21
21
 
22
- redis.zrangebyscore(key_group_key(options), 0, Time.now.to_i).to_a.map { |key| self.new(key, options) }
22
+ redis.zrangebyscore(key_group_key(options), 0, Time.now.to_i).to_a.map do |key_token|
23
+ key, token = key_token.scan(/(.*):(.*)$/).first
24
+ self.new(key, options.merge(:token => token))
25
+ end
26
+ end
27
+
28
+ def all(options={})
29
+ redis = options[:redis] || self.redis
30
+ raise "redis cannot be nil" if redis.nil?
31
+
32
+ redis.zrangebyscore(key_group_key(options), 0, "+inf").to_a.map do |key_token|
33
+ key, token = key_token.scan(/(.*):(.*)$/).first
34
+ self.new(key, options.merge(:token => token))
35
+ end
23
36
  end
24
37
 
25
38
  def key_group_key(options)
@@ -44,6 +57,7 @@ class Redis::Lock
44
57
  @timeout = @options[:timeout] || self.class.timeout
45
58
  @expire = @options[:expire] || self.class.expire
46
59
  @sleep = @options[:sleep] || self.class.sleep
60
+ @token = @options[:token]
47
61
  end
48
62
 
49
63
  def synchronize(&block)
@@ -54,6 +68,7 @@ class Redis::Lock
54
68
  try_unlock
55
69
  end
56
70
  rescue Recovered
71
+ block.call
57
72
  end
58
73
 
59
74
  def lock(options={})
@@ -91,18 +106,22 @@ class Redis::Lock
91
106
  local next_token = redis.call('incr', token_key)
92
107
 
93
108
  redis.call('hset', key, 'expires_at', expires_at)
94
- redis.call('hset', key, 'token', next_token)
95
- redis.call('zadd', key_group, expires_at, bare_key)
109
+ redis.call('zadd', key_group, expires_at, bare_key .. ':' .. next_token)
96
110
 
111
+ local return_value = nil
97
112
  if prev_expires_at then
98
- return {'recovered', next_token, redis.call('hget', key, 'recovery_data')}
113
+ redis.call('zrem', key_group, bare_key .. ':' .. redis.call('hget', key, 'token'))
114
+ return_value = {'recovered', next_token, redis.call('hget', key, 'recovery_data')}
99
115
  else
100
116
  redis.call('hset', key, 'recovery_data', recovery_data)
101
- return {'acquired', next_token, nil}
117
+ return_value = {'acquired', next_token, nil}
102
118
  end
119
+
120
+ redis.call('hset', key, 'token', next_token)
121
+ return return_value
103
122
  LUA
104
123
  result, token, recovery_data = @@lock_script.eval(@redis,
105
- :keys => [NAMESPACE + @key, @key_group_key],
124
+ :keys => [namespaced_key, @key_group_key],
106
125
  :argv => [@key, now.to_i, now.to_i + @expire, options[:recovery_data]])
107
126
 
108
127
  case result
@@ -134,13 +153,13 @@ class Redis::Lock
134
153
 
135
154
  if redis.call('hget', key, 'token') == token then
136
155
  redis.call('del', key)
137
- redis.call('zrem', key_group, bare_key)
156
+ redis.call('zrem', key_group, bare_key .. ':' .. token)
138
157
  return true
139
158
  else
140
159
  return false
141
160
  end
142
161
  LUA
143
- !!@@unlock_script.eval(@redis, :keys => [NAMESPACE + @key, @key_group_key], :argv => [@key, @token])
162
+ !!@@unlock_script.eval(@redis, :keys => [namespaced_key, @key_group_key], :argv => [@key, @token])
144
163
  end
145
164
 
146
165
  def extend
@@ -154,16 +173,30 @@ class Redis::Lock
154
173
  local bare_key = ARGV[1]
155
174
  local expires_at = tonumber(ARGV[2])
156
175
  local token = ARGV[3]
176
+ local token_key = 'redis:lock:token'
157
177
 
158
178
  if redis.call('hget', key, 'token') == token then
179
+ local next_token = redis.call('incr', token_key)
180
+
159
181
  redis.call('hset', key, 'expires_at', expires_at)
160
- redis.call('zadd', key_group, expires_at, bare_key)
161
- return true
182
+ redis.call('hset', key, 'token', next_token)
183
+
184
+ redis.call('zrem', key_group, bare_key .. ':' .. token)
185
+ redis.call('zadd', key_group, expires_at, bare_key .. ':' .. next_token)
186
+
187
+ return { next_token, redis.call('hget', key, 'recovery_data') }
162
188
  else
163
189
  return false
164
190
  end
165
191
  LUA
166
- !!@@extend_script.eval(@redis, :keys => [NAMESPACE + @key, @key_group_key], :argv => [@key, now.to_i + @expire, @token])
192
+ result = @@extend_script.eval(@redis, :keys => [namespaced_key, @key_group_key], :argv => [@key, now.to_i + @expire, @token])
193
+
194
+ if result
195
+ @token, @recovery_data = result
196
+ true
197
+ else
198
+ false
199
+ end
167
200
  end
168
201
 
169
202
  def now
@@ -178,7 +211,11 @@ class Redis::Lock
178
211
  @key
179
212
  end
180
213
 
181
- class ErrorBase < RuntimeError
214
+ def namespaced_key
215
+ NAMESPACE + ':' + @key
216
+ end
217
+
218
+ class Error < RuntimeError
182
219
  attr_reader :lock
183
220
 
184
221
  def initialize(lock)
@@ -186,19 +223,19 @@ class Redis::Lock
186
223
  end
187
224
  end
188
225
 
189
- class LostLock < ErrorBase
226
+ class LostLock < Error
190
227
  def message
191
228
  "The following lock was lost while trying to modify: #{@lock}"
192
229
  end
193
230
  end
194
231
 
195
- class Redis::Lock::Recovered < ErrorBase
232
+ class Recovered < Error
196
233
  def message
197
234
  "The following lock was recovered: #{@lock}"
198
235
  end
199
236
  end
200
237
 
201
- class Redis::Lock::Timeout < ErrorBase
238
+ class Timeout < Error
202
239
  def message
203
240
  "The following lock timed-out waiting to get aquired: #{@lock}"
204
241
  end
@@ -1,5 +1,5 @@
1
1
  class Redis
2
2
  class Lock
3
- VERSION = '1.0.0'
3
+ VERSION = '1.0.1'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: robust-redis-lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kareem Kouddous
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-16 00:00:00.000000000 Z
11
+ date: 2015-05-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -54,7 +54,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
54
54
  version: '0'
55
55
  requirements: []
56
56
  rubyforge_project:
57
- rubygems_version: 2.2.0
57
+ rubygems_version: 2.2.2
58
58
  signing_key:
59
59
  specification_version: 4
60
60
  summary: Robust redis lock