remote_lock 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [![Build Status](https://travis-ci.org/HouseTrip/remote_lock.png)](https://travis-ci.org/HouseTrip/remote_lock)
1
+ [![Build Status](https://travis-ci.org/HouseTrip/remote_lock.png)](https://travis-ci.org/HouseTrip/remote_lock) [![Code Climate](https://codeclimate.com/github/HouseTrip/remote_lock.png)](https://codeclimate.com/github/HouseTrip/remote_lock)
2
2
 
3
3
  remote_lock
4
4
  ===========
@@ -12,7 +12,7 @@ Installation
12
12
  ------------
13
13
 
14
14
  ```shell
15
- gem install remote-lock
15
+ gem install remote_lock
16
16
  ```
17
17
 
18
18
  Initialization
@@ -4,8 +4,25 @@ module RemoteLock::Adapters
4
4
  class Redis < Base
5
5
 
6
6
  def store(key, expires_in_seconds)
7
- @connection.setnx(key, uid).tap do |status|
8
- @connection.expire(key, expires_in_seconds) if status
7
+ # The previous implementation used SETNX and EXPIRE in sequence to set the
8
+ # lock. in case a previous client failed between SETNX and EXPIRE below,
9
+ # the key may not expire.
10
+ # We wrap setting the value and its expiry timestamp in a transaction.
11
+ #
12
+ # Caveat emptor: Redis transactions are *very* different from SQL
13
+ # transactions.
14
+
15
+ # cancel the next transaction if another client touches our key past
16
+ # this point
17
+ @connection.watch(key)
18
+
19
+ # check if another client has the key.
20
+ # it's important to still run a transaction to clear the watch.
21
+ have_competition = @connection.exists(key)
22
+
23
+ !! @connection.multi do
24
+ break if have_competition
25
+ @connection.setex(key, expires_in_seconds, uid)
9
26
  end
10
27
  end
11
28
 
@@ -1,3 +1,3 @@
1
1
  class RemoteLock
2
- VERSION = "1.0.0"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -20,6 +20,15 @@ module RemoteLock::Adapters
20
20
  redis.get(test_key).should eq uid
21
21
  end
22
22
 
23
+ it 'return truthy on success' do
24
+ adapter.store(test_key, 100).should be_true
25
+ end
26
+
27
+ it 'return falsy on failure' do
28
+ redis.set(test_key, uid)
29
+ adapter.store(test_key, 100).should be_false
30
+ end
31
+
23
32
  context "expiry" do
24
33
  it "should expire the key after the time is over" do
25
34
  adapter.store(test_key, 1)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: remote_lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-11-08 00:00:00.000000000 Z
16
+ date: 2014-02-08 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: rake
@@ -170,7 +170,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
170
170
  version: '0'
171
171
  segments:
172
172
  - 0
173
- hash: 589636169546274691
173
+ hash: -816774539149081442
174
174
  required_rubygems_version: !ruby/object:Gem::Requirement
175
175
  none: false
176
176
  requirements:
@@ -179,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
179
  version: '0'
180
180
  segments:
181
181
  - 0
182
- hash: 589636169546274691
182
+ hash: -816774539149081442
183
183
  requirements: []
184
184
  rubyforge_project:
185
185
  rubygems_version: 1.8.23