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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e211a307e1814231fd3bff20fe5a435c4086bd4b
4
- data.tar.gz: 8eff81ba4ddc1bdbd434cc730c676684b3b6a24f
3
+ metadata.gz: 6fc0883b1b090a5d98583474945925da5f32a383
4
+ data.tar.gz: e6763a3272de61da92bd839d2b6a5034e56ed874
5
5
  SHA512:
6
- metadata.gz: c5066ccec8e8b53c5b8f8a58c0d80740921a7627431918ed2a92d3533620c6fa1787c72d3aeaa7b6f0ce6899b434ddd236b14ee1c3c87435e357b1890040bf34
7
- data.tar.gz: 77b1d0ba859c9e7b0dd04ee59473c9aefc2e785ca03a131902c342da4c6418eee9646f7b0626b38e2bc821ad8ca6560a8c7f087cae1f10be4655d9f20a327e6f
6
+ metadata.gz: cfa994d572aa72130f2749cbceae0e148e6ed8aab2f7ca9c53fbd8d3525abd1a0f9dfdfc63474297f79e331a7ea92a802c433f9caca4ba26afd9a13ff7f11a09
7
+ data.tar.gz: 2f7fe9f173577b854789821ddb3d739e078e5e210e5ca49d7c7d716ba22772deceb5a1947609c8a3c1f8dcb40126726f5df45532811381b5e6de9b86c40e13c9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ # 0.3.2 (2016-08-29)
2
+
3
+ Enhancements:
4
+
5
+ * Add #try_lock
6
+
1
7
  # 0.3.1 (2016-08-29)
2
8
 
3
9
  Enhancements:
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
@@ -1,3 +1,3 @@
1
1
  class RedisGetlock
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  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
- return yield
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
- current = Time.now.to_f
93
- payload = {uuid: uuid, expire_at: (current + expire).to_s}.to_json
94
- return true if redis.set(key, payload, {nx: true, ex: expire}) # key does not exist
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
- current = Time.now.to_f
105
- payload = {uuid: uuid, expire_at: (current + expire).to_s}.to_json
106
- if redis.setnx(key, payload) # key does not exist
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.1
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-28 00:00:00.000000000 Z
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/try
89
+ - bin/try_lock
89
90
  - lib/redis_getlock.rb
90
91
  - lib/redis_getlock/version.rb
91
92
  - redis_getlock.gemspec