robust-redis-lock 1.0.0 → 1.0.1

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