redis-semaphore 0.2.4 → 0.3.0
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 +5 -13
- data/README.md +25 -1
- data/lib/redis/semaphore.rb +15 -4
- data/spec/semaphore_spec.rb +27 -2
- metadata +19 -21
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MjI5YzlmMzBhOWE2ZmUwZTQyNjQ0Y2JjM2ZkMzZhOWEzMTc0YWZkOA==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 309187f46b275cd806075cad1bbe6957dac9b81d
|
4
|
+
data.tar.gz: 290e95937ffc62ca1026be42ad33d2b9017be559
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
YjZiZTZlZTBmYzQ0MWFlNjFlNzFiODVjOTc4YjAyOWRiODUwYWY4MjNiNmYy
|
11
|
-
ZDAyZDEwOTZjZjk3ODVmMWIyNmJkNWZiYmEyMzM4ZDNjYmU2MTI=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
MTdhN2RjYTRjMDIxMGJhNTM4YWM0YTViYzNjM2FjYmJmMjBmYjgwZGZjMDE0
|
14
|
-
MGNiZmM3YjI3OTJiNmU5OTAyZTZhNWVmOGFlNzQyZjMxNTYwZmIzMDY2NGU3
|
15
|
-
NTA4NTBkMGNiZjRhNmQzZjEyNjM4ZjMwNzFjYTI4YzgxZWFiYzg=
|
6
|
+
metadata.gz: bc1eefa40196e5e95f8c4f74258b8136eb8179262a784bff743c5729a17631de3fbbd7b13b888eaffd43b7b63de8fa3209ea226d3009d66de9a18467742be594
|
7
|
+
data.tar.gz: 8c69c42bfb18035f63fb15d94cbd92593344a2e08dee9883ddde9598e534dcef0227a6d51542496cea6582ac9c1751d7fe830965e5134e62502c5a7c886c0ca7
|
data/README.md
CHANGED
@@ -10,6 +10,23 @@ The mutex and semaphore is blocking, not polling, and has a fair queue serving p
|
|
10
10
|
|
11
11
|
For more info see [Wikipedia](http://en.wikipedia.org/wiki/Semaphore_(programming)).
|
12
12
|
|
13
|
+
Changes for 0.3.0
|
14
|
+
=================
|
15
|
+
|
16
|
+
If you've been using `redis-semaphore` before version `0.3.0` you should be aware that the interface for `lock` has changed slightly. Before `0.3` calling `semaphore.lock(0)` (with `0` as the timeout) would block the semaphore indefinitely, just like a redis `blpop` command would.
|
17
|
+
|
18
|
+
This has changed in `0.3` to mean *do not block at all*. You can still omit the argument entirely, or pass in `nil` to get the old functionality back. Examples:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
# These block indefinitely until a resource becomes available:
|
22
|
+
semaphore.lock
|
23
|
+
semaphore.lock(nil)
|
24
|
+
|
25
|
+
# This does not block at all and rather returns immediately if there's no
|
26
|
+
# resource available:
|
27
|
+
semaphore.lock(0)
|
28
|
+
```
|
29
|
+
|
13
30
|
Usage
|
14
31
|
-----
|
15
32
|
|
@@ -200,9 +217,15 @@ Testing
|
|
200
217
|
Changelog
|
201
218
|
---------
|
202
219
|
|
220
|
+
###0.3.0 January 24, 2016
|
221
|
+
- Change API to include non-blocking option for `#lock` (thanks tomclose!).
|
222
|
+
- Fix unwanted persisting of `available_key` (thanks dany1468!).
|
223
|
+
- Fix `available_count` returning 0 for nonexisting semaphores (thanks mikeryz!).
|
224
|
+
|
203
225
|
###0.2.4 January 11, 2015
|
204
226
|
- Fix bug with TIME and redis-namespace (thanks sos4nt!).
|
205
227
|
- Add expiration option (thanks jcalvert!).
|
228
|
+
- Update API version logic.
|
206
229
|
|
207
230
|
###0.2.3 September 7, 2014
|
208
231
|
- Block-based locking return the value of the block (thanks frobcode!).
|
@@ -266,4 +289,5 @@ Thanks to these awesome people for their contributions:
|
|
266
289
|
- [Petteri Räty](https://github.com/betelgeuse)
|
267
290
|
- [Stefan Schüßler](https://github.com/sos4nt)
|
268
291
|
- [Jonathan Calvert](https://github.com/jcalvert)
|
269
|
-
|
292
|
+
- [mikeryz](https://github.com/mikeryz)
|
293
|
+
- [tomclose](https://github.com/tomclose)
|
data/lib/redis/semaphore.rb
CHANGED
@@ -37,13 +37,16 @@ class Redis
|
|
37
37
|
@redis.set(version_key, API_VERSION)
|
38
38
|
end
|
39
39
|
|
40
|
-
set_expiration_if_necessary
|
41
40
|
true
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|
45
44
|
def available_count
|
46
|
-
|
45
|
+
if exists?
|
46
|
+
@redis.llen(available_key)
|
47
|
+
else
|
48
|
+
@resource_count
|
49
|
+
end
|
47
50
|
end
|
48
51
|
|
49
52
|
def delete!
|
@@ -53,11 +56,17 @@ class Redis
|
|
53
56
|
@redis.del(version_key)
|
54
57
|
end
|
55
58
|
|
56
|
-
def lock(timeout =
|
59
|
+
def lock(timeout = nil)
|
57
60
|
exists_or_create!
|
58
61
|
release_stale_locks! if check_staleness?
|
59
62
|
|
60
|
-
|
63
|
+
if timeout.nil? || timeout > 0
|
64
|
+
# passing timeout 0 to blpop causes it to block
|
65
|
+
token_pair = @redis.blpop(available_key, timeout || 0)
|
66
|
+
else
|
67
|
+
token_pair = @redis.lpop(available_key)
|
68
|
+
end
|
69
|
+
|
61
70
|
return false if token_pair.nil?
|
62
71
|
|
63
72
|
current_token = token_pair[1]
|
@@ -100,6 +109,8 @@ class Redis
|
|
100
109
|
@redis.multi do
|
101
110
|
@redis.hdel grabbed_key, token
|
102
111
|
@redis.lpush available_key, token
|
112
|
+
|
113
|
+
set_expiration_if_necessary
|
103
114
|
end
|
104
115
|
end
|
105
116
|
|
data/spec/semaphore_spec.rb
CHANGED
@@ -22,6 +22,10 @@ describe "redis" do
|
|
22
22
|
expect(semaphore.available_count).to eq(1)
|
23
23
|
end
|
24
24
|
|
25
|
+
it "has the correct amount of available resources before locking" do
|
26
|
+
expect(semaphore.available_count).to eq(1)
|
27
|
+
end
|
28
|
+
|
25
29
|
it "should not exist from the start" do
|
26
30
|
expect(semaphore.exists?).to eq(false)
|
27
31
|
semaphore.lock
|
@@ -89,9 +93,9 @@ describe "redis" do
|
|
89
93
|
it "should not leave the semaphore locked after raising an exception" do
|
90
94
|
expect {
|
91
95
|
semaphore.lock(1) do
|
92
|
-
raise Exception
|
96
|
+
raise Exception, "redis semaphore exception"
|
93
97
|
end
|
94
|
-
}.to raise_error
|
98
|
+
}.to raise_error(Exception, "redis semaphore exception")
|
95
99
|
|
96
100
|
expect(semaphore.locked?).to eq(false)
|
97
101
|
end
|
@@ -121,6 +125,18 @@ describe "redis" do
|
|
121
125
|
|
122
126
|
expect(@redis.keys.count).to eq(original_key_size)
|
123
127
|
end
|
128
|
+
|
129
|
+
it "should not block when the timeout is zero" do
|
130
|
+
did_we_get_in = false
|
131
|
+
|
132
|
+
semaphore.lock do
|
133
|
+
semaphore.lock(0) do
|
134
|
+
did_we_get_in = true
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
expect(did_we_get_in).to be false
|
139
|
+
end
|
124
140
|
end
|
125
141
|
|
126
142
|
describe "semaphore with expiration" do
|
@@ -135,6 +151,15 @@ describe "redis" do
|
|
135
151
|
sleep 3.0
|
136
152
|
expect(@redis.keys.count).to eq(original_key_size)
|
137
153
|
end
|
154
|
+
|
155
|
+
it "expires keys after unlocking" do
|
156
|
+
original_key_size = @redis.keys.count
|
157
|
+
semaphore.lock do
|
158
|
+
# noop
|
159
|
+
end
|
160
|
+
sleep 3.0
|
161
|
+
expect(@redis.keys.count).to eq(original_key_size)
|
162
|
+
end
|
138
163
|
end
|
139
164
|
|
140
165
|
describe "semaphore without staleness checking" do
|
metadata
CHANGED
@@ -1,98 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-semaphore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Verhasselt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '2.14'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.14'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pry
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: timecop
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
-
description:
|
84
|
-
|
85
|
-
'
|
83
|
+
description: |
|
84
|
+
Implements a distributed semaphore or mutex using Redis.
|
86
85
|
email: david@crowdway.com
|
87
86
|
executables: []
|
88
87
|
extensions: []
|
89
88
|
extra_rdoc_files: []
|
90
89
|
files:
|
90
|
+
- LICENSE
|
91
91
|
- README.md
|
92
92
|
- Rakefile
|
93
|
-
- LICENSE
|
94
|
-
- lib/redis/semaphore.rb
|
95
93
|
- lib/redis-semaphore.rb
|
94
|
+
- lib/redis/semaphore.rb
|
96
95
|
- spec/semaphore_spec.rb
|
97
96
|
- spec/spec_helper.rb
|
98
97
|
homepage: http://github.com/dv/redis-semaphore
|
@@ -105,19 +104,18 @@ require_paths:
|
|
105
104
|
- lib
|
106
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
107
106
|
requirements:
|
108
|
-
- -
|
107
|
+
- - ">="
|
109
108
|
- !ruby/object:Gem::Version
|
110
109
|
version: '0'
|
111
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
111
|
requirements:
|
113
|
-
- -
|
112
|
+
- - ">="
|
114
113
|
- !ruby/object:Gem::Version
|
115
114
|
version: '0'
|
116
115
|
requirements: []
|
117
116
|
rubyforge_project:
|
118
|
-
rubygems_version: 2.
|
117
|
+
rubygems_version: 2.4.5
|
119
118
|
signing_key:
|
120
119
|
specification_version: 4
|
121
120
|
summary: Implements a distributed semaphore or mutex using Redis.
|
122
121
|
test_files: []
|
123
|
-
has_rdoc:
|