robust-redis-lock 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/redis-lock.rb +31 -13
- data/lib/robust-redis-lock/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff73b4f537214a712e375526275c68be1037ea7e
|
4
|
+
data.tar.gz: 50257826714c16e8cba1658f89fac74e65a9452f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dd8d1e3474a94440fe7cde4a04c005337acdba1fa1c0b700a39e00fb03e559b76a4e941f32dca30ed6618513d47f3f9ffc8e28c4efe7ee04b7b11a01e2fb2c1d
|
7
|
+
data.tar.gz: 72dd7a3174784487cca91c6bfa8dbd52621edbafc8c696ab88421c13bdeba670a5b23a8d875441574a952c747b85d616d6a553e38b750a44c1db97bb08a1fe6e
|
data/lib/redis-lock.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'redis'
|
2
|
+
require 'yaml'
|
2
3
|
|
3
4
|
class Redis::Lock
|
4
5
|
require 'robust-redis-lock/script'
|
@@ -12,6 +13,7 @@ class Redis::Lock
|
|
12
13
|
attr_accessor :expire
|
13
14
|
attr_accessor :namespace
|
14
15
|
attr_accessor :key_group
|
16
|
+
attr_accessor :serializer
|
15
17
|
|
16
18
|
def expired(options={})
|
17
19
|
self.redis.zrangebyscore(key_group_key(options), 0, Time.now.to_i).map { |key| self.new(key, options) }
|
@@ -26,26 +28,36 @@ class Redis::Lock
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
29
|
-
self.timeout
|
30
|
-
self.expire
|
31
|
-
self.sleep
|
32
|
-
self.namespace
|
33
|
-
self.key_group
|
31
|
+
self.timeout = 60
|
32
|
+
self.expire = 60
|
33
|
+
self.sleep = 0.1
|
34
|
+
self.namespace = 'redis:lock'
|
35
|
+
self.key_group = 'default'
|
36
|
+
self.serializer = YAML
|
34
37
|
|
35
|
-
def initialize(
|
38
|
+
def initialize(*args)
|
39
|
+
raise "invalid number of args: expected 1..3, got #{args.length}" if args.length < 1 || args.length > 3
|
40
|
+
|
41
|
+
key = args.shift
|
36
42
|
raise "key cannot be nil" if key.nil?
|
37
|
-
@options = options
|
38
43
|
|
39
|
-
|
44
|
+
if args.length == 2
|
45
|
+
@data = args.shift
|
46
|
+
end
|
47
|
+
|
48
|
+
@options = args.shift || {}
|
49
|
+
|
50
|
+
namespace_prefix = self.class.namespace_prefix(@options) unless key.start_with?(self.class.namespace_prefix(@options))
|
40
51
|
@key = [namespace_prefix, key].compact.join(':')
|
41
52
|
@key_group_key = self.class.key_group_key(@options)
|
42
53
|
|
43
|
-
@redis = options[:redis] || self.class.redis
|
54
|
+
@redis = @options[:redis] || self.class.redis
|
44
55
|
raise "redis cannot be nil" if @redis.nil?
|
45
56
|
|
46
|
-
@timeout
|
47
|
-
@expire
|
48
|
-
@sleep
|
57
|
+
@timeout = @options[:timeout] || self.class.timeout
|
58
|
+
@expire = @options[:expire] || self.class.expire
|
59
|
+
@sleep = @options[:sleep] || self.class.sleep
|
60
|
+
@serializer = @options[:serializer] || self.class.serializer
|
49
61
|
end
|
50
62
|
|
51
63
|
def lock
|
@@ -63,6 +75,10 @@ class Redis::Lock
|
|
63
75
|
unlock if block_given?
|
64
76
|
end
|
65
77
|
|
78
|
+
def data
|
79
|
+
@data ||= @serializer.load(@redis.hget(key, 'data'))
|
80
|
+
end
|
81
|
+
|
66
82
|
def try_lock
|
67
83
|
# This script loading is not thread safe (touching a class variable), but
|
68
84
|
# that's okay, because the race is harmless.
|
@@ -71,6 +87,7 @@ class Redis::Lock
|
|
71
87
|
local key_group = KEYS[2]
|
72
88
|
local now = tonumber(ARGV[1])
|
73
89
|
local expires_at = tonumber(ARGV[2])
|
90
|
+
local data = ARGV[3]
|
74
91
|
local token_key = 'redis:lock:token'
|
75
92
|
|
76
93
|
local prev_expires_at = tonumber(redis.call('hget', key, 'expires_at'))
|
@@ -82,6 +99,7 @@ class Redis::Lock
|
|
82
99
|
|
83
100
|
redis.call('hset', key, 'expires_at', expires_at)
|
84
101
|
redis.call('hset', key, 'token', next_token)
|
102
|
+
redis.call('hset', key, 'data', data)
|
85
103
|
redis.call('zadd', key_group, expires_at, key)
|
86
104
|
|
87
105
|
if prev_expires_at then
|
@@ -90,7 +108,7 @@ class Redis::Lock
|
|
90
108
|
return {'acquired', next_token}
|
91
109
|
end
|
92
110
|
LUA
|
93
|
-
result, token = @@lock_script.eval(@redis, :keys => [@key, @key_group_key], :argv => [now.to_i, now.to_i + @expire])
|
111
|
+
result, token = @@lock_script.eval(@redis, :keys => [@key, @key_group_key], :argv => [now.to_i, now.to_i + @expire, @serializer.dump(@data)])
|
94
112
|
|
95
113
|
@token = token if token
|
96
114
|
|