redis_getlock 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +2 -0
- data/bin/{try → lock} +0 -0
- data/bin/try_lock +35 -0
- data/lib/redis_getlock/version.rb +1 -1
- data/lib/redis_getlock.rb +54 -18
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6fc0883b1b090a5d98583474945925da5f32a383
|
4
|
+
data.tar.gz: e6763a3272de61da92bd839d2b6a5034e56ed874
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfa994d572aa72130f2749cbceae0e148e6ed8aab2f7ca9c53fbd8d3525abd1a0f9dfdfc63474297f79e331a7ea92a802c433f9caca4ba26afd9a13ff7f11a09
|
7
|
+
data.tar.gz: 2f7fe9f173577b854789821ddb3d739e078e5e210e5ca49d7c7d716ba22772deceb5a1947609c8a3c1f8dcb40126726f5df45532811381b5e6de9b86c40e13c9
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -84,6 +84,8 @@ Similarly with ruby standard library [mutex](https://ruby-doc.org/core-2.2.0/Mut
|
|
84
84
|
* Releases the lock. Returns true if successfully released a lock
|
85
85
|
* self_locked?
|
86
86
|
* Returns true if this lock is currently held by myself.
|
87
|
+
* try_lock
|
88
|
+
* Attempts to grab the lock and returns immediately without waits. Returns true if successfully acquired a lock
|
87
89
|
|
88
90
|
Options of `RedisGetlock.new` are:
|
89
91
|
|
data/bin/{try → lock}
RENAMED
File without changes
|
data/bin/try_lock
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "redis_getlock"
|
5
|
+
require 'logger'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
opts = {
|
9
|
+
kill: false
|
10
|
+
}
|
11
|
+
OptionParser.new.tap {|op|
|
12
|
+
op.on('--kill') {|v|
|
13
|
+
opts[:kill] = true
|
14
|
+
}
|
15
|
+
op.parse(ARGV)
|
16
|
+
}
|
17
|
+
|
18
|
+
if opts[:kill]
|
19
|
+
trap('INT') do
|
20
|
+
exit!
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
mutex = RedisGetlock.new(
|
25
|
+
redis: Redis.new, key: 'redis_getlock', logger: Logger.new(STDOUT),
|
26
|
+
timeout: -1,
|
27
|
+
)
|
28
|
+
if mutex.try_lock
|
29
|
+
loop do
|
30
|
+
puts "locked?:#{mutex.locked?} self_locked?:#{mutex.self_locked?}"
|
31
|
+
sleep 1
|
32
|
+
end
|
33
|
+
else
|
34
|
+
puts 'exit'
|
35
|
+
end
|
data/lib/redis_getlock.rb
CHANGED
@@ -6,7 +6,7 @@ require 'json'
|
|
6
6
|
class RedisGetlock
|
7
7
|
attr_reader :redis, :key, :logger, :timeout, :expire, :interval, :uuid
|
8
8
|
|
9
|
-
TIMEOUT = -1
|
9
|
+
TIMEOUT = -1 # infinity
|
10
10
|
EXPIRE = 2
|
11
11
|
INTERVAL = 1
|
12
12
|
|
@@ -40,6 +40,23 @@ class RedisGetlock
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
def try_lock
|
44
|
+
if set_options_available?
|
45
|
+
locked = try_lock_with_set_options
|
46
|
+
else
|
47
|
+
locked = try_lock_without_set_options
|
48
|
+
end
|
49
|
+
@thr.terminate if @thr and @thr.alive?
|
50
|
+
if locked
|
51
|
+
@thr = Thread.new(&method(:keeplock))
|
52
|
+
logger.info { "#{log_head}Acquired a redis lock '#{key}'" } if logger
|
53
|
+
true
|
54
|
+
else
|
55
|
+
logger.info { "#{log_head}A redis lock is already acquired '#{key}'" } if logger
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
43
60
|
def unlock
|
44
61
|
@thr.terminate if @thr and @thr.alive?
|
45
62
|
if self_locked?
|
@@ -66,7 +83,7 @@ class RedisGetlock
|
|
66
83
|
def synchronize(&block)
|
67
84
|
raise LockError unless lock
|
68
85
|
begin
|
69
|
-
|
86
|
+
yield
|
70
87
|
ensure
|
71
88
|
unlock
|
72
89
|
end
|
@@ -89,32 +106,51 @@ class RedisGetlock
|
|
89
106
|
def lock_with_set_options
|
90
107
|
started = Time.now.to_f
|
91
108
|
loop do
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
return false if timeout >= 0 and (current - started) >= timeout
|
109
|
+
locked = try_lock_with_set_options
|
110
|
+
return true if locked
|
111
|
+
break if timeout >= 0 and (Time.now.to_f - started) >= timeout
|
96
112
|
sleep interval
|
97
113
|
end
|
114
|
+
false
|
98
115
|
end
|
99
116
|
|
100
117
|
# redis < 2.6.12
|
101
118
|
# ref. http://redis.io/commands/setnx
|
102
119
|
def lock_without_set_options
|
120
|
+
started = Time.now.to_f
|
103
121
|
loop do
|
104
|
-
|
105
|
-
|
106
|
-
if
|
107
|
-
redis.expire(key, expire)
|
108
|
-
return true # acquire lock
|
109
|
-
end
|
110
|
-
previous = JSON.parse(redis.get(key))
|
111
|
-
if previous['expire_at'].to_f < current # key exists, but previous
|
112
|
-
compared = redis.getset(key, paylod)
|
113
|
-
return true if previous['expire_at'] == compared['expire_at'] # acquire lock
|
114
|
-
end
|
115
|
-
return false if timeout >= 0 and (current - started) >= timeout
|
122
|
+
locked = try_lock_without_set_options
|
123
|
+
return true if locked
|
124
|
+
break if timeout >= 0 and (Time.now.to_f - started) >= timeout
|
116
125
|
sleep interval
|
117
126
|
end
|
127
|
+
false
|
128
|
+
end
|
129
|
+
|
130
|
+
# redis >= 2.6.12
|
131
|
+
# ref. http://redis.io/commands/set
|
132
|
+
def try_lock_with_set_options
|
133
|
+
current = Time.now.to_f
|
134
|
+
payload = {uuid: uuid, expire_at: (current + expire).to_s}.to_json
|
135
|
+
return true if redis.set(key, payload, {nx: true, ex: expire}) # key does not exist
|
136
|
+
false
|
137
|
+
end
|
138
|
+
|
139
|
+
# redis < 2.6.12
|
140
|
+
# ref. http://redis.io/commands/setnx
|
141
|
+
def try_lock_without_set_options
|
142
|
+
current = Time.now.to_f
|
143
|
+
payload = {uuid: uuid, expire_at: (current + expire).to_s}.to_json
|
144
|
+
if redis.setnx(key, payload) # key does not exist
|
145
|
+
redis.expire(key, expire)
|
146
|
+
return true # acquire lock
|
147
|
+
end
|
148
|
+
previous = JSON.parse(redis.get(key))
|
149
|
+
if previous['expire_at'].to_f < current # key exists, but previous
|
150
|
+
compared = redis.getset(key, paylod)
|
151
|
+
return true if previous['expire_at'] == compared['expire_at'] # acquire lock
|
152
|
+
end
|
153
|
+
false
|
118
154
|
end
|
119
155
|
|
120
156
|
def keeplock
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_getlock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Naotoshi Seo
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
@@ -84,8 +84,9 @@ files:
|
|
84
84
|
- README.md
|
85
85
|
- Rakefile
|
86
86
|
- bin/console
|
87
|
+
- bin/lock
|
87
88
|
- bin/setup
|
88
|
-
- bin/
|
89
|
+
- bin/try_lock
|
89
90
|
- lib/redis_getlock.rb
|
90
91
|
- lib/redis_getlock/version.rb
|
91
92
|
- redis_getlock.gemspec
|