redlock 0.1.1 → 0.1.2

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
- N2ZjYTlmOTc2ZTc0MmYxZGE0MzBiNzY2ZjEzOGMxOWU4YjE3NzRhMQ==
5
- data.tar.gz: !binary |-
6
- NjMwOGMxNTRkMDliODFmYjI3YWY5MWQ3ZTdjMjUzMDNlNTdiNDQ4Yg==
2
+ SHA1:
3
+ metadata.gz: e2d0a189eba4a2f362d02f034cfa0957eba666eb
4
+ data.tar.gz: 18f9e90023c218eb9b5d65a71946b39fb98a8617
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZTg2ZTI4MzY0ZmI3MzhkYzlhNTA3NzVjMGYyZmJlNGVhNjAzODE0ZGY4M2Qz
10
- NDI2ODJmYzU5MGI2YjM3MmMxNGQwNTRlYzM4ZTE0MWNhNmQyYWVlNGUyYmU4
11
- YWM0OTUyMzQwNzdlNTk2ZTNiNGE4OTdjYTQzYmYwMjBjYjU5YmE=
12
- data.tar.gz: !binary |-
13
- N2Q1ZTcwZWRlNDYyZjY0MzY4MDA4ZTVhMjEwNTE3N2Q4MWZmOTY0MDA0MmIx
14
- MjVlYzM3ZWQ1Y2RkODJiOTI0ZTZiYWQ3MjdmZWU2NWZkNzMyMGM2YzM2OTUy
15
- NWJmMjNmNjU0YzgyNDNkNGVhMDM2OWJjZmMzY2NhMWY4MzVjZjI=
6
+ metadata.gz: 65cd0b7c60b9756eba2f0fcce27677b9f26e32db74f3cbea7f036744ae52bfd0e50f8ce72cddb538fafc49a409c0f7a6257976d9234be8305d8a77151958980d
7
+ data.tar.gz: 0531fe15435ad4601ad83c8aa107ac6e3073f4f2be49682c74ff379f9b9c20f603e140b51c604b5baffdfb7650a3e4762cdea9495870fa1b684f99bcbab6930d
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redlock (0.1.0)
4
+ redlock (0.1.2)
5
5
  redis (~> 3, >= 3.0.5)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -84,7 +84,7 @@ end
84
84
  Make sure you have at least 1 redis instances up.
85
85
 
86
86
  $ rspec
87
-
87
+
88
88
  ## Disclaimer
89
89
 
90
90
  This code implements an algorithm which is currently a proposal, it was not formally analyzed. Make sure to understand how it works before using it in your production environments. You can see discussion about this approach at [reddit](http://www.reddit.com/r/programming/comments/2nt0nq/distributed_lock_using_redis_implemented_in_ruby/).
@@ -74,6 +74,8 @@ module Redlock
74
74
  else
75
75
  @redis = Redis.new(connection)
76
76
  end
77
+
78
+ load_scripts
77
79
  end
78
80
 
79
81
  def lock(resource, val, ttl)
@@ -81,10 +83,16 @@ module Redlock
81
83
  end
82
84
 
83
85
  def unlock(resource, val)
84
- @redis.eval(UNLOCK_SCRIPT, [resource], [val])
86
+ @redis.evalsha(@unlock_script_sha, keys: [resource], argv: [val])
85
87
  rescue
86
88
  # Nothing to do, unlocking is just a best-effort attempt.
87
89
  end
90
+
91
+ private
92
+
93
+ def load_scripts
94
+ @unlock_script_sha = @redis.script(:load, UNLOCK_SCRIPT)
95
+ end
88
96
  end
89
97
 
90
98
  def try_lock_instances(resource, ttl)
@@ -0,0 +1,37 @@
1
+ module Redlock
2
+ class Client
3
+ attr_writer :testing_mode
4
+
5
+ alias_method :try_lock_instances_without_testing, :try_lock_instances
6
+
7
+ def try_lock_instances(resource, ttl)
8
+ if @testing_mode == :bypass
9
+ {
10
+ validity: ttl,
11
+ resource: resource,
12
+ value: SecureRandom.uuid
13
+ }
14
+ elsif @testing_mode == :fail
15
+ false
16
+ else
17
+ try_lock_instances_without_testing resource, ttl
18
+ end
19
+ end
20
+
21
+ alias_method :unlock_without_testing, :unlock
22
+
23
+ def unlock(lock_info)
24
+ unlock_without_testing lock_info unless @testing_mode == :bypass
25
+ end
26
+
27
+ class RedisInstance
28
+ def load_scripts
29
+ begin
30
+ @unlock_script_sha = @redis.script(:load, UNLOCK_SCRIPT)
31
+ rescue Redis::CommandError
32
+ # ignore
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,3 @@
1
1
  module Redlock
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -9,14 +9,14 @@ RSpec.describe Redlock::Client do
9
9
 
10
10
  describe 'initialize' do
11
11
  it 'accepts both redis URLs and Redis objects' do
12
- servers = [ 'redis://localhost:6379', Redis.new(url: 'redis://someotherhost:6379') ]
12
+ servers = [ 'redis://localhost:6379', Redis.new(url: 'redis://127.0.0.1:6379') ]
13
13
  redlock = Redlock::Client.new(servers)
14
14
 
15
15
  redlock_servers = redlock.instance_variable_get(:@servers).map do |s|
16
16
  s.instance_variable_get(:@redis).client.host
17
17
  end
18
18
 
19
- expect(redlock_servers).to match_array(%w{ localhost someotherhost })
19
+ expect(redlock_servers).to match_array(%w{ localhost 127.0.0.1 })
20
20
  end
21
21
  end
22
22
 
@@ -1,5 +1,4 @@
1
1
  # coding: utf-8
2
- # $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
2
  require 'coveralls'
4
3
  Coveralls.wear!
5
4
  require 'redlock'
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'securerandom'
3
+
4
+ require 'redlock/testing'
5
+
6
+ RSpec.describe Redlock::Client do
7
+ let(:lock_manager) { Redlock::Client.new }
8
+ let(:resource_key) { SecureRandom.hex(3) }
9
+ let(:ttl) { 1000 }
10
+
11
+ describe '(testing mode)' do
12
+ describe 'try_lock_instances' do
13
+ context 'when testing with bypass mode' do
14
+ before { lock_manager.testing_mode = :bypass }
15
+
16
+ it 'bypasses the redis servers' do
17
+ expect(lock_manager).to_not receive(:try_lock_instances_without_testing)
18
+ lock_manager.lock(resource_key, ttl) do |lock_info|
19
+ expect(lock_info).to be_lock_info_for(resource_key)
20
+ end
21
+ end
22
+ end
23
+
24
+ context 'when testing with fail mode' do
25
+ before { lock_manager.testing_mode = :fail }
26
+
27
+ it 'fails' do
28
+ expect(lock_manager).to_not receive(:try_lock_instances_without_testing)
29
+ lock_manager.lock(resource_key, ttl) do |lock_info|
30
+ expect(lock_info).to eql(false)
31
+ end
32
+ end
33
+ end
34
+
35
+ context 'when testing is disabled' do
36
+ before { lock_manager.testing_mode = nil }
37
+
38
+ it 'works as usual' do
39
+ expect(lock_manager).to receive(:try_lock_instances_without_testing)
40
+ lock_manager.lock(resource_key, ttl) { |lock_info| }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redlock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Moreira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-21 00:00:00.000000000 Z
11
+ date: 2015-09-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -17,7 +17,7 @@ dependencies:
17
17
  - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3'
20
- - - ! '>='
20
+ - - '>='
21
21
  - !ruby/object:Gem::Version
22
22
  version: 3.0.5
23
23
  type: :runtime
@@ -27,7 +27,7 @@ dependencies:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
29
  version: '3'
30
- - - ! '>='
30
+ - - '>='
31
31
  - !ruby/object:Gem::Version
32
32
  version: 3.0.5
33
33
  - !ruby/object:Gem::Dependency
@@ -48,14 +48,14 @@ dependencies:
48
48
  name: coveralls
49
49
  requirement: !ruby/object:Gem::Requirement
50
50
  requirements:
51
- - - ! '>='
51
+ - - '>='
52
52
  - !ruby/object:Gem::Version
53
53
  version: '0'
54
54
  type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
- - - ! '>='
58
+ - - '>='
59
59
  - !ruby/object:Gem::Version
60
60
  version: '0'
61
61
  - !ruby/object:Gem::Dependency
@@ -104,10 +104,12 @@ files:
104
104
  - Rakefile
105
105
  - lib/redlock.rb
106
106
  - lib/redlock/client.rb
107
+ - lib/redlock/testing.rb
107
108
  - lib/redlock/version.rb
108
109
  - redlock.gemspec
109
110
  - spec/client_spec.rb
110
111
  - spec/spec_helper.rb
112
+ - spec/testing_spec.rb
111
113
  homepage: https://github.com/leandromoreira/redlock-rb
112
114
  licenses:
113
115
  - BSD-2-Clause
@@ -118,12 +120,12 @@ require_paths:
118
120
  - lib
119
121
  required_ruby_version: !ruby/object:Gem::Requirement
120
122
  requirements:
121
- - - ! '>='
123
+ - - '>='
122
124
  - !ruby/object:Gem::Version
123
125
  version: '0'
124
126
  required_rubygems_version: !ruby/object:Gem::Requirement
125
127
  requirements:
126
- - - ! '>='
128
+ - - '>='
127
129
  - !ruby/object:Gem::Version
128
130
  version: '0'
129
131
  requirements: []
@@ -135,3 +137,4 @@ summary: Distributed lock using Redis written in Ruby.
135
137
  test_files:
136
138
  - spec/client_spec.rb
137
139
  - spec/spec_helper.rb
140
+ - spec/testing_spec.rb