redlock 1.3.2 → 2.0.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.
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