redis-semaphore 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- MjdjZjZhZWZiNmZiYTY1YWJkMWQ0ZDUyYmJjZGY2NGViMzQzZDhmMA==
5
- data.tar.gz: !binary |-
6
- MjI5YzlmMzBhOWE2ZmUwZTQyNjQ0Y2JjM2ZkMzZhOWEzMTc0YWZkOA==
2
+ SHA1:
3
+ metadata.gz: 309187f46b275cd806075cad1bbe6957dac9b81d
4
+ data.tar.gz: 290e95937ffc62ca1026be42ad33d2b9017be559
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YzZjOTA0ZWQ2OWUzMzk2YTYyODA1ZWIzYjBiZmU1MTc5Yjg4MTk0MDZjYWYz
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)
@@ -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
- @redis.llen(available_key)
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 = 0)
59
+ def lock(timeout = nil)
57
60
  exists_or_create!
58
61
  release_stale_locks! if check_staleness?
59
62
 
60
- token_pair = @redis.blpop(available_key, timeout)
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
 
@@ -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.2.4
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: 2015-01-11 00:00:00.000000000 Z
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: ! 'Implements a distributed semaphore or mutex using Redis.
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.1.10
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: