redis_getlock 0.3.1 → 0.3.2
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 +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
|