redlock 1.3.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7de9b6b9d70bce2578e474bdfe8dfa15c22bb57e0c876ac7127d826a5b6ba9b4
4
- data.tar.gz: c294d219107aa4a8682ba4ff303e150497ea61b2dd4abb71d3cac15e78c218bd
3
+ metadata.gz: 679d1c44fcda7a2eaa70bdfe38c30e4ee79e417bef0b3ce064aceaf0a9cc0bbb
4
+ data.tar.gz: 48b6a41c4cc27b8ff8878647dd494a6b87e3b17e540b75d8699e32d4ee982aa5
5
5
  SHA512:
6
- metadata.gz: b0eeead2b1307f12487603d72a7a5e00d6aba1d697a5327ac484a4fa4cc00575e0fcedd43a38aa34ee93da7322550630ad3cec158a5ef0fcf98849033c90ec85
7
- data.tar.gz: 712d3c40ab8c4278f4649f373bfcb6ca4eeb2361461a48ad42d17f44a9d1becba460b82ed99f6b035232698267ad5046831230960b47171d9fa09d9ba0d4b692
6
+ metadata.gz: a31815a7da2fa6f5c3af35734294cdb34fdfba19dc12eaf25abe950db65be1356afc397ff29a73823d267d99d0069f86651385c1e262da6ced7541345212abda
7
+ data.tar.gz: cd4e41fe60732180b4b5f3d848715954074f8a063c1513c89e73a37311d5d4c0d8fbe1bbd92b063955324929f07bf59232040de104bfeb14d18837d297910d59
@@ -2,9 +2,9 @@ name: Ruby CI
2
2
 
3
3
  on:
4
4
  push:
5
- branches: [ master ]
5
+ branches: [ main ]
6
6
  pull_request:
7
- branches: [ master ]
7
+ branches: [ main ]
8
8
 
9
9
  jobs:
10
10
  test:
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  coverage/
3
3
  .bundle/
4
4
  dump.rdb
5
+ Gemfile.lock
data/Makefile CHANGED
@@ -7,6 +7,3 @@ build:
7
7
 
8
8
  publish:
9
9
  docker-compose run --rm test gem push `ls -lt *gem | head -n 1 | awk '{ print $$9 }'`
10
-
11
- updateLock:
12
- docker-compose run --rm test bundle lock --update
data/README.md CHANGED
@@ -15,7 +15,7 @@ This is an implementation of a proposed [distributed lock algorithm with Redis](
15
15
 
16
16
  ## Compatibility
17
17
 
18
- Redlock works with Redis versions 2.6 or later.
18
+ Redlock works with Redis versions 6.0 or later.
19
19
 
20
20
  ## Installation
21
21
 
@@ -151,7 +151,7 @@ lock_manager.get_remaining_ttl_for_lock(lock_info)
151
151
 
152
152
  lock_manager.unlock(lock_info)
153
153
  lock_manager.get_remaining_ttl_for_lock(lock_info)
154
- #=> nil
154
+ #=> nil
155
155
  ```
156
156
 
157
157
  Use `get_remaining_ttl_for_resource` if you do not hold a lock, but want to know the remaining TTL on a locked resource:
@@ -164,13 +164,13 @@ lock_info = lock_manager.lock(resource, 2000)
164
164
  lock_manager.locked?(resource)
165
165
  #=> true
166
166
  lock_manager.get_remaining_ttl_for_resource(resource)
167
- #=> 1975
167
+ #=> 1975
168
168
 
169
169
  # Sometime later
170
170
  lock_manager.locked?(resource)
171
171
  #=> false
172
172
  lock_manager.get_remaining_ttl_for_resource(resource)
173
- #=> nil
173
+ #=> nil
174
174
  ```
175
175
 
176
176
  ## Redis client configuration
@@ -178,7 +178,7 @@ lock_manager.get_remaining_ttl_for_resource(resource)
178
178
  `Redlock::Client` expects URLs or Redis objects on initialization. Redis objects should be used for configuring the connection in more detail, i.e. setting username and password.
179
179
 
180
180
  ```ruby
181
- servers = [ 'redis://localhost:6379', Redis.new(:url => 'redis://someotherhost:6379') ]
181
+ servers = [ 'redis://localhost:6379', RedisClient.new(:url => 'redis://someotherhost:6379') ]
182
182
  redlock = Redlock::Client.new(servers)
183
183
  ```
184
184
 
@@ -1,4 +1,4 @@
1
- require 'redis'
1
+ require 'redis-client'
2
2
  require 'securerandom'
3
3
 
4
4
  module Redlock
@@ -160,7 +160,7 @@ module Redlock
160
160
  if connection.respond_to?(:client)
161
161
  @redis = connection
162
162
  else
163
- @redis = Redis.new(connection)
163
+ @redis = RedisClient.new(connection)
164
164
  end
165
165
  @redis.extend(ConnectionPoolLike)
166
166
  end
@@ -168,13 +168,13 @@ module Redlock
168
168
 
169
169
  def lock(resource, val, ttl, allow_new_lock)
170
170
  recover_from_script_flush do
171
- @redis.with { |conn| conn.evalsha Scripts::LOCK_SCRIPT_SHA, keys: [resource], argv: [val, ttl, allow_new_lock] }
171
+ @redis.call('EVALSHA', Scripts::LOCK_SCRIPT_SHA, 1, resource, val, ttl, allow_new_lock)
172
172
  end
173
173
  end
174
174
 
175
175
  def unlock(resource, val)
176
176
  recover_from_script_flush do
177
- @redis.with { |conn| conn.evalsha Scripts::UNLOCK_SCRIPT_SHA, keys: [resource], argv: [val] }
177
+ @redis.call('EVALSHA', Scripts::UNLOCK_SCRIPT_SHA, 1, resource, val)
178
178
  end
179
179
  rescue
180
180
  # Nothing to do, unlocking is just a best-effort attempt.
@@ -182,9 +182,9 @@ module Redlock
182
182
 
183
183
  def get_remaining_ttl(resource)
184
184
  recover_from_script_flush do
185
- @redis.with { |conn| conn.evalsha Scripts::PTTL_SCRIPT_SHA, keys: [resource] }
185
+ @redis.call('EVALSHA', Scripts::PTTL_SCRIPT_SHA, 1, resource)
186
186
  end
187
- rescue Redis::BaseConnectionError
187
+ rescue RedisClient::ConnectionError
188
188
  nil
189
189
  end
190
190
 
@@ -197,8 +197,10 @@ module Redlock
197
197
  Scripts::PTTL_SCRIPT
198
198
  ]
199
199
 
200
- scripts.each do |script|
201
- @redis.with { |conn| conn.script(:load, script) }
200
+ @redis.with do |connnection|
201
+ scripts.each do |script|
202
+ connnection.call('SCRIPT', 'LOAD', script)
203
+ end
202
204
  end
203
205
  end
204
206
 
@@ -206,7 +208,7 @@ module Redlock
206
208
  retry_on_noscript = true
207
209
  begin
208
210
  yield
209
- rescue Redis::CommandError => e
211
+ rescue RedisClient::CommandError => e
210
212
  # When somebody has flushed the Redis instance's script cache, we might
211
213
  # want to reload our scripts. Only attempt this once, though, to avoid
212
214
  # going into an infinite loop.
@@ -41,7 +41,7 @@ module Redlock
41
41
 
42
42
  def load_scripts
43
43
  load_scripts_without_testing unless Redlock::Client.testing_mode == :bypass
44
- rescue Redis::CommandError
44
+ rescue RedisClient::CommandError
45
45
  # FakeRedis doesn't have #script, but doesn't need it either.
46
46
  raise unless defined?(::FakeRedis)
47
47
  rescue NoMethodError
@@ -1,3 +1,3 @@
1
1
  module Redlock
2
- VERSION = '1.3.2'
2
+ VERSION = '2.0.0'
3
3
  end
data/redlock.gemspec CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency 'redis', '>= 3.0.0', '< 6.0'
21
+ spec.add_dependency 'redis-client'
22
22
 
23
23
  spec.add_development_dependency 'connection_pool', '~> 2.2'
24
24
  spec.add_development_dependency 'coveralls', '~> 0.8'
data/spec/client_spec.rb CHANGED
@@ -1,13 +1,12 @@
1
1
  require 'spec_helper'
2
2
  require 'securerandom'
3
- require 'redis'
4
3
  require 'connection_pool'
5
4
 
6
5
  RSpec.describe Redlock::Client do
7
6
  # It is recommended to have at least 3 servers in production
8
7
  let(:lock_manager_opts) { { retry_count: 3 } }
9
8
  let(:lock_manager) { Redlock::Client.new(Redlock::Client::DEFAULT_REDIS_URLS, lock_manager_opts) }
10
- let(:redis_client) { Redis.new(url: "redis://#{redis1_host}:#{redis1_port}") }
9
+ let(:redis_client) { RedisClient.new(url: "redis://#{redis1_host}:#{redis1_port}") }
11
10
  let(:resource_key) { SecureRandom.hex(3) }
12
11
  let(:ttl) { 1000 }
13
12
  let(:redis1_host) { ENV["REDIS1_HOST"] || "localhost" }
@@ -17,7 +16,7 @@ RSpec.describe Redlock::Client do
17
16
  let(:redis3_host) { ENV["REDIS3_HOST"] || "127.0.0.1" }
18
17
  let(:redis3_port) { ENV["REDIS3_PORT"] || "6379" }
19
18
  let(:unreachable_redis) {
20
- redis = Redis.new(url: 'redis://localhost:46864')
19
+ redis = RedisClient.new(url: 'redis://localhost:46864')
21
20
  def redis.with
22
21
  yield self
23
22
  end
@@ -26,18 +25,18 @@ RSpec.describe Redlock::Client do
26
25
 
27
26
  describe 'initialize' do
28
27
  it 'accepts both redis URLs and Redis objects' do
29
- servers = [ "redis://#{redis1_host}:#{redis1_port}", Redis.new(url: "redis://#{redis2_host}:#{redis2_port}") ]
28
+ servers = [ "redis://#{redis1_host}:#{redis1_port}", RedisClient.new(url: "redis://#{redis2_host}:#{redis2_port}") ]
30
29
  redlock = Redlock::Client.new(servers)
31
30
 
32
31
  redlock_servers = redlock.instance_variable_get(:@servers).map do |s|
33
- s.instance_variable_get(:@redis).connection[:host]
32
+ s.instance_variable_get(:@redis).config.host
34
33
  end
35
34
 
36
35
  expect(redlock_servers).to match_array([redis1_host, redis2_host])
37
36
  end
38
37
 
39
38
  it 'accepts ConnectionPool objects' do
40
- pool = ConnectionPool.new { Redis.new(url: "redis://#{redis1_host}:#{redis1_port}") }
39
+ pool = ConnectionPool.new { RedisClient.new(url: "redis://#{redis1_host}:#{redis1_port}") }
41
40
  redlock = Redlock::Client.new([pool])
42
41
 
43
42
  lock_info = lock_manager.lock(resource_key, ttl)
@@ -46,12 +45,15 @@ RSpec.describe Redlock::Client do
46
45
  end
47
46
 
48
47
  it 'does not load scripts' do
49
- redis_client.script(:flush)
48
+ redis_client.call('SCRIPT', 'FLUSH')
50
49
 
51
- pool = ConnectionPool.new { Redis.new(url: "redis://#{redis1_host}:#{redis1_port}") }
50
+ pool = ConnectionPool.new { RedisClient.new(url: "redis://#{redis1_host}:#{redis1_port}") }
52
51
  redlock = Redlock::Client.new([pool])
53
52
 
54
- expect(redis_client.info["number_of_cached_scripts"]).to eq("0")
53
+ raw_info = redis_client.call('INFO')
54
+ number_of_cached_scripts = raw_info[/number_of_cached_scripts\:\d+/].split(':').last
55
+
56
+ expect(number_of_cached_scripts).to eq("0")
55
57
  end
56
58
  end
57
59
 
@@ -74,7 +76,7 @@ RSpec.describe Redlock::Client do
74
76
  it 'interprets lock time as milliseconds' do
75
77
  ttl = 20000
76
78
  @lock_info = lock_manager.lock(resource_key, ttl)
77
- expect(redis_client.pttl(resource_key)).to be_within(200).of(ttl)
79
+ expect(redis_client.call('PTTL', resource_key)).to be_within(200).of(ttl)
78
80
  end
79
81
 
80
82
  it 'can extend its own lock' do
@@ -106,7 +108,7 @@ RSpec.describe Redlock::Client do
106
108
 
107
109
  lock_info = lock_manager.lock(resource_key, ttl, extend: lock_info, extend_only_if_locked: true)
108
110
  expect(lock_info).not_to be_nil
109
- expect(redis_client.pttl(resource_key)).to be_within(200).of(ttl)
111
+ expect(redis_client.call('PTTL', resource_key)).to be_within(200).of(ttl)
110
112
  end
111
113
 
112
114
  context 'when extend_only_if_locked flag is not given' do
@@ -249,7 +251,7 @@ RSpec.describe Redlock::Client do
249
251
 
250
252
  expect {
251
253
  lock_manager.lock(resource_key, ttl)
252
- }.to raise_error(Redis::CannotConnectError)
254
+ }.to raise_error(RedisClient::CannotConnectError)
253
255
  end
254
256
  end
255
257
 
@@ -261,7 +263,7 @@ RSpec.describe Redlock::Client do
261
263
  redis_instance.instance_variable_set(:@redis, unreachable_redis)
262
264
  expect {
263
265
  lock_manager.lock(resource_key, ttl)
264
- }.to raise_error(Redis::CannotConnectError)
266
+ }.to raise_error(RedisClient::CannotConnectError)
265
267
  redis_instance.instance_variable_set(:@redis, old_redis)
266
268
  expect(lock_manager.lock(resource_key, ttl)).to be_truthy
267
269
  end
@@ -270,10 +272,10 @@ RSpec.describe Redlock::Client do
270
272
  context 'when script cache has been flushed' do
271
273
  before(:each) do
272
274
  @manipulated_instance = lock_manager.instance_variable_get(:@servers).first
273
- @manipulated_instance.instance_variable_get(:@redis).script(:flush)
275
+ @manipulated_instance.instance_variable_get(:@redis).call('SCRIPT', 'FLUSH')
274
276
  end
275
277
 
276
- it 'does not raise a Redis::CommandError: NOSCRIPT error' do
278
+ it 'does not raise a RedisClient::CommandError: NOSCRIPT error' do
277
279
  expect {
278
280
  lock_manager.lock(resource_key, ttl)
279
281
  }.to_not raise_error
metadata CHANGED
@@ -1,35 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redlock
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Moreira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-17 00:00:00.000000000 Z
11
+ date: 2023-02-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: redis
14
+ name: redis-client
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.0
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '6.0'
19
+ version: '0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
24
  - - ">="
28
25
  - !ruby/object:Gem::Version
29
- version: 3.0.0
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '6.0'
26
+ version: '0'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: connection_pool
35
29
  requirement: !ruby/object:Gem::Requirement
@@ -102,22 +96,22 @@ dependencies:
102
96
  name: rspec
103
97
  requirement: !ruby/object:Gem::Requirement
104
98
  requirements:
105
- - - "~>"
106
- - !ruby/object:Gem::Version
107
- version: '3'
108
99
  - - ">="
109
100
  - !ruby/object:Gem::Version
110
101
  version: 3.0.0
102
+ - - "~>"
103
+ - !ruby/object:Gem::Version
104
+ version: '3'
111
105
  type: :development
112
106
  prerelease: false
113
107
  version_requirements: !ruby/object:Gem::Requirement
114
108
  requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '3'
118
109
  - - ">="
119
110
  - !ruby/object:Gem::Version
120
111
  version: 3.0.0
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: '3'
121
115
  description: Distributed lock using Redis written in Ruby. Highly inspired by https://github.com/antirez/redlock-rb.
122
116
  email:
123
117
  - leandro.ribeiro.moreira@gmail.com
@@ -130,7 +124,6 @@ files:
130
124
  - ".rspec"
131
125
  - CONTRIBUTORS
132
126
  - Gemfile
133
- - Gemfile.lock
134
127
  - LICENSE
135
128
  - Makefile
136
129
  - README.md
@@ -165,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
165
158
  - !ruby/object:Gem::Version
166
159
  version: '0'
167
160
  requirements: []
168
- rubygems_version: 3.3.7
161
+ rubygems_version: 3.0.3.1
169
162
  signing_key:
170
163
  specification_version: 4
171
164
  summary: Distributed lock using Redis written in Ruby.
data/Gemfile.lock DELETED
@@ -1,62 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- redlock (1.3.2)
5
- redis (>= 3.0.0, < 6.0)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- connection_pool (2.3.0)
11
- coveralls (0.8.23)
12
- json (>= 1.8, < 3)
13
- simplecov (~> 0.16.1)
14
- term-ansicolor (~> 1.3)
15
- thor (>= 0.19.4, < 2.0)
16
- tins (~> 1.6)
17
- diff-lcs (1.5.0)
18
- docile (1.4.0)
19
- json (2.3.1)
20
- rake (13.0.6)
21
- redis (5.0.5)
22
- redis-client (>= 0.9.0)
23
- redis-client (0.10.0)
24
- connection_pool
25
- rspec (3.11.0)
26
- rspec-core (~> 3.11.0)
27
- rspec-expectations (~> 3.11.0)
28
- rspec-mocks (~> 3.11.0)
29
- rspec-core (3.11.0)
30
- rspec-support (~> 3.11.0)
31
- rspec-expectations (3.11.1)
32
- diff-lcs (>= 1.2.0, < 2.0)
33
- rspec-support (~> 3.11.0)
34
- rspec-mocks (3.11.1)
35
- diff-lcs (>= 1.2.0, < 2.0)
36
- rspec-support (~> 3.11.0)
37
- rspec-support (3.11.1)
38
- simplecov (0.16.1)
39
- docile (~> 1.1)
40
- json (>= 1.8, < 3)
41
- simplecov-html (~> 0.10.0)
42
- simplecov-html (0.10.2)
43
- sync (0.5.0)
44
- term-ansicolor (1.7.1)
45
- tins (~> 1.0)
46
- thor (1.2.1)
47
- tins (1.31.1)
48
- sync
49
-
50
- PLATFORMS
51
- ruby
52
-
53
- DEPENDENCIES
54
- connection_pool (~> 2.2)
55
- coveralls (~> 0.8)
56
- json (~> 2.3.1, >= 2.3.0)
57
- rake (~> 13.0, >= 11.1.2)
58
- redlock!
59
- rspec (~> 3, >= 3.0.0)
60
-
61
- BUNDLED WITH
62
- 2.3.7