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