remote_lock 1.0.0 → 1.1.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.
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