sidekiq-lock 0.5.0 → 0.7.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: 592d4bf95b4bbd2cba2444898c5f6843c0a9112c6c45e018999af361b8a5ca73
4
- data.tar.gz: 7b0a5614796a292af28fc0880915a76ac85ecfb8c669b07d57d5019d8f246342
3
+ metadata.gz: b9c3099623c0436cfe8cbd6eb0d3f56168ac0fda088b7167a0211ca4cba6e530
4
+ data.tar.gz: b5105d14dd29c9374b43a46cba4cfd6c576f086808051949bf4729c9163be05e
5
5
  SHA512:
6
- metadata.gz: ff115e3d009c6b6803e20326c2d84bf2286d9e4b652fe840b743596b8257919d7c54b3f1b9e1dcf2f9f1cba16af6541490464a77d55b52ff1b9407f28a7981f3
7
- data.tar.gz: 0cf165b35136db26001b236837dcd7a831867fc81d8b81a3e14c2efe76edf41ade9cb5ba437b311b9ec1626af5aae176a3a09fde0c393ef5b949f2f5e5f8fa64
6
+ metadata.gz: 18898eaacf8fd60adeee2dce1e53e96bf517878856541220cbb472338dd7e4f531463917fb059b0767bb411834fe42f23aac535cb078f814de76de4bda8c3bfc
7
+ data.tar.gz: 07ee42bde63d54ef88ad56625167f781b259943967507fefe4769735377f12fd12dbf28985b3c0a4cf5d4a950a3162367bdcc78ce17f5ff346003c22ff38ecab
data/CHANGELOG.md CHANGED
@@ -1,3 +1,14 @@
1
+ ## 0.7.0 (Feb 7, 2024)
2
+
3
+ - support for Sidekiq 7.2 (thanks for the issue report [9mm](https://github.com/9mm))
4
+ - dropped support for Sidekiq 5 and older [as it reached EOL](https://github.com/sidekiq/sidekiq/wiki/Commercial-Support#version-policy)
5
+ - removed `redis` as gem dependency (relying on sidekiq version you're using to choose the right one)
6
+
7
+ ## 0.6.0 (May 27, 2023)
8
+
9
+ - support for Sidekiq 7 (thanks to [@stympy](https://github.com/stympy))
10
+ - move CI pipelines to Github Actions - drop tests for everything below Sidekiq 5, run tests on redis 6.2 & 7.0 and ruby 2.6 - 3.1
11
+
1
12
  ## 0.5.0 (August 13, 2021)
2
13
 
3
14
  - maintenance - test on latest ruby versions (remove outdated rubies from build), add sidekiq 6 to build matrix, remove coveralls
data/LICENSE.txt CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013 Rafal Wojsznis
1
+ Copyright (c) 2024 Rafal Wojsznis
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,11 +1,10 @@
1
1
  <p align="center">
2
- <img width="300" height="210" src="https://github.com/emq/sidekiq-lock/raw/master/logo.png">
2
+ <img width="300" height="210" src="https://github.com/rwojsznis/sidekiq-lock/raw/main/logo.png">
3
3
  </p>
4
4
 
5
5
  # Sidekiq::Lock
6
6
 
7
- [![Code Climate](https://codeclimate.com/github/emq/sidekiq-lock.png)](https://codeclimate.com/github/emq/sidekiq-lock)
8
- [![Build Status](https://travis-ci.com/rwojsznis/sidekiq-lock.svg?branch=master)](https://travis-ci.com/rwojsznis/sidekiq-lock)
7
+ [![Code Climate](https://codeclimate.com/github/rwojsznis/sidekiq-lock.png)](https://codeclimate.com/github/rwojsznis/sidekiq-lock)
9
8
  [![Gem Version](https://badge.fury.io/rb/sidekiq-lock.png)](http://badge.fury.io/rb/sidekiq-lock)
10
9
 
11
10
  **Note:** This is a _complete_ piece of software, it should work across all future sidekiq & ruby versions.
@@ -19,7 +18,7 @@ time - it provides a `lock` method that you can use in whatever way you want.
19
18
 
20
19
  This gem requires at least:
21
20
  - redis 2.6.12
22
- - redis-rb 3.0.5 (support for extended SET method)
21
+ - sidekiq 6
23
22
 
24
23
  Add this line to your application's Gemfile:
25
24
 
@@ -23,18 +23,21 @@ module Sidekiq
23
23
  # this also requires redis-rb >= 3.0.5
24
24
  def acquire!
25
25
  @acquired ||= Sidekiq.redis do |r|
26
- r.set(name, value, nx: true, px: timeout)
26
+ if Sidekiq::VERSION >= '7.2'
27
+ r.set(name, value, 'nx', 'px', timeout)
28
+ else
29
+ r.set(name, value, nx: true, px: timeout)
30
+ end
27
31
  end
28
32
  end
29
33
 
30
34
  def release!
31
- Sidekiq.redis do |r|
32
- begin
33
- r.evalsha redis_lock_script_sha, keys: [name], argv: [value]
34
- rescue Redis::CommandError
35
- r.eval redis_lock_script, keys: [name], argv: [value]
36
- end
37
- end
35
+ # even if lock expired / was take over by another process
36
+ # it still means from our perspective that we released it
37
+ @acquired = false
38
+
39
+ # https://redis.io/commands/del/#return
40
+ release_lock == 1
38
41
  end
39
42
 
40
43
  def name
@@ -53,6 +56,27 @@ module Sidekiq
53
56
 
54
57
  attr_reader :options, :payload
55
58
 
59
+ def release_lock
60
+ # Sidekiq 7 uses redis-client gem, designed for redis 6+
61
+ if Sidekiq::VERSION >= '7'
62
+ Sidekiq.redis do |r|
63
+ begin
64
+ r.evalsha redis_lock_script_sha, [name], [value]
65
+ rescue RedisClient::CommandError
66
+ r.eval redis_lock_script, 1, [name], [value]
67
+ end
68
+ end
69
+ else
70
+ Sidekiq.redis do |r|
71
+ begin
72
+ r.evalsha redis_lock_script_sha, keys: [name], argv: [value]
73
+ rescue Redis::CommandError
74
+ r.eval redis_lock_script, keys: [name], argv: [value]
75
+ end
76
+ end
77
+ end
78
+ end
79
+
56
80
  def redis_lock_script_sha
57
81
  @lock_script_sha ||= Digest::SHA1.hexdigest redis_lock_script
58
82
  end
@@ -1,5 +1,5 @@
1
1
  module Sidekiq
2
2
  module Lock
3
- VERSION = '0.5.0'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  end
@@ -4,26 +4,27 @@ require 'open3'
4
4
  module Sidekiq
5
5
  describe Lock do
6
6
  it 'automatically loads lock middleware for sidekiq server' do
7
- skip 'Sidekiq 2 does not print out middleware information' if Sidekiq::VERSION < '3.0.0'
7
+ skip 'Sidekiq 7+ does not print out middleware information' if Sidekiq::VERSION >= '7'
8
8
 
9
9
  cmd = 'sidekiq -r ./test/test_workers.rb -v'
10
- buffer = ''
10
+ buffer_out = ''
11
11
 
12
12
  # very not fancy (https://78.media.tumblr.com/tumblr_lzkpw7DAl21qhy6c9o2_400.gif)
13
13
  # solution, but should do the job
14
14
  Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
15
15
  begin
16
- Timeout.timeout(5) do
16
+ Timeout.timeout(3) do
17
17
  until stdout.eof? do
18
- buffer << stdout.read_nonblock(16)
18
+ buffer_out << stdout.read_nonblock(16)
19
19
  end
20
20
  end
21
+
21
22
  rescue Timeout::Error
22
23
  Process.kill('KILL', thread.pid)
23
24
  end
24
25
  end
25
26
 
26
- assert_match(/\s?Middleware:.*Sidekiq::Lock::Middleware/i, buffer)
27
+ assert_match(/\s?Middleware:.*Sidekiq::Lock::Middleware/i, buffer_out)
27
28
  end
28
29
  end
29
30
  end
@@ -4,14 +4,19 @@ module Sidekiq
4
4
  module Lock
5
5
  describe Middleware do
6
6
  before do
7
- Sidekiq.redis = REDIS
7
+ if Sidekiq::VERSION >= '7'
8
+ Sidekiq.configure_server do |config|
9
+ config.redis = { url: REDIS_URL }
10
+ end
11
+ else
12
+ Sidekiq.redis = REDIS
13
+ end
8
14
  Sidekiq.redis { |c| c.flushdb }
9
15
  reset_lock_variable!
10
16
  end
11
17
 
12
- let(:handler) { Sidekiq::Lock::Middleware.new }
13
-
14
18
  it 'sets lock variable with provided static lock options' do
19
+ handler = Sidekiq::Lock::Middleware.new
15
20
  handler.call(LockWorker.new, { 'class' => LockWorker, 'args' => [] }, 'default') do
16
21
  true
17
22
  end
@@ -20,6 +25,7 @@ module Sidekiq
20
25
  end
21
26
 
22
27
  it 'sets lock variable with provided dynamic options' do
28
+ handler = Sidekiq::Lock::Middleware.new
23
29
  handler.call(DynamicLockWorker.new, { 'class' => DynamicLockWorker, 'args' => [1234, 1000] }, 'default') do
24
30
  true
25
31
  end
@@ -29,6 +35,7 @@ module Sidekiq
29
35
  end
30
36
 
31
37
  it 'sets nothing for workers without lock options' do
38
+ handler = Sidekiq::Lock::Middleware.new
32
39
  handler.call(RegularWorker.new, { 'class' => RegularWorker, 'args' => [] }, 'default') do
33
40
  true
34
41
  end
@@ -4,12 +4,16 @@ module Sidekiq
4
4
  module Lock
5
5
  describe RedisLock do
6
6
  before do
7
- Sidekiq.redis = REDIS
7
+ if Sidekiq::VERSION >= '7'
8
+ Sidekiq.configure_client do |config|
9
+ config.redis = { url: REDIS_URL }
10
+ end
11
+ else
12
+ Sidekiq.redis = REDIS
13
+ end
8
14
  Sidekiq.redis { |c| c.flushdb }
9
15
  end
10
16
 
11
- let(:args) { [{'timeout' => 100, 'name' => 'test-lock'}, []] }
12
-
13
17
  it "raises an error on missing timeout&name values" do
14
18
  assert_raises ArgumentError do
15
19
  RedisLock.new({},[])
@@ -52,46 +56,59 @@ module Sidekiq
52
56
  end
53
57
 
54
58
  it "can acquire a lock" do
55
- lock = RedisLock.new(*args)
59
+ lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock'}, [])
60
+ assert lock.acquire!
61
+ end
62
+
63
+ it "sets proper lock value on first and second acquire" do
64
+ lock = RedisLock.new({'timeout' => 1000, 'name' => 'test-lock', 'value' => 'lock value'}, [])
56
65
  assert lock.acquire!
66
+ assert_equal 'lock value', redis("get", lock.name)
67
+ assert lock.release!
68
+ # at this point script should be used from evalsha
69
+ assert lock.acquire!
70
+ assert_equal 'lock value', redis("get", lock.name)
71
+
72
+ redis("script", "flush")
73
+ assert lock.acquire!
74
+ assert_equal 'lock value', redis("get", lock.name)
57
75
  end
58
76
 
59
- it "cannot aquire lock if it's already taken by other process/thread" do
60
- faster_lock = RedisLock.new(*args)
77
+ it "cannot acquire lock if it's already taken by other process/thread" do
78
+ faster_lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock'}, [])
61
79
  assert faster_lock.acquire!
62
80
 
63
- slower_lock = RedisLock.new(*args)
81
+ slower_lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock'}, [])
64
82
  refute slower_lock.acquire!
65
83
  end
66
84
 
67
85
  it "releases taken lock" do
68
- lock = RedisLock.new(*args)
86
+ lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock'}, [])
69
87
  lock.acquire!
70
88
  assert redis("get", "test-lock")
71
89
 
72
- lock.release!
90
+ assert lock.release!
73
91
  assert_nil redis("get", "test-lock")
74
92
  end
75
93
 
76
94
  it "releases lock taken by another process without deleting lock key" do
77
- lock = RedisLock.new(*args)
95
+ lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock'}, [])
78
96
  lock.acquire!
79
97
  lock_value = redis("get", "test-lock")
80
98
  assert lock_value
81
99
  sleep 0.11 # timeout lock
82
100
 
83
- new_lock = RedisLock.new(*args)
101
+ new_lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock'}, [])
84
102
  new_lock.acquire!
85
103
  new_lock_value = redis("get", "test-lock")
86
104
 
87
- lock.release!
105
+ refute lock.release!
88
106
 
89
107
  assert_equal new_lock_value, redis("get", "test-lock")
90
108
  end
91
109
 
92
110
  it "releases taken lock" do
93
- custom_args = [args.first.merge('value' => 'custom_value'), []]
94
- lock = RedisLock.new(*custom_args)
111
+ lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock', 'value' => 'custom_value'}, [])
95
112
  lock.acquire!
96
113
  assert redis("get", "test-lock")
97
114
 
@@ -3,8 +3,6 @@ require 'test_helper'
3
3
  module Sidekiq
4
4
  module Lock
5
5
  describe Worker do
6
- # after { }
7
-
8
6
  class CustomContainer
9
7
  def initialize
10
8
  @lock = nil
@@ -19,47 +17,38 @@ module Sidekiq
19
17
  end
20
18
  end
21
19
 
22
- # it 'sets lock method that points to thread variable' do
23
- # set_lock_variable! "test"
24
- # assert_equal "test", LockWorker.new.lock
25
- # end
26
-
27
20
  it 'allows method name configuration' do
28
- begin
29
- Sidekiq.lock_method = :custom_lock_name
21
+ Sidekiq.lock_method = :custom_lock_name
30
22
 
31
- class WorkerWithCustomLockName
32
- include Sidekiq::Worker
33
- include Sidekiq::Lock::Worker
34
- end
23
+ class WorkerWithCustomLockName
24
+ include Sidekiq::Worker
25
+ include Sidekiq::Lock::Worker
26
+ end
35
27
 
36
- set_lock_variable! "custom_name"
28
+ set_lock_variable! "custom_name"
37
29
 
38
- assert_equal "custom_name", WorkerWithCustomLockName.new.custom_lock_name
30
+ assert_equal "custom_name", WorkerWithCustomLockName.new.custom_lock_name
39
31
 
40
- reset_lock_variable!
41
- ensure
32
+ reset_lock_variable!
33
+ ensure
42
34
 
43
- Sidekiq.lock_method = Sidekiq::Lock::METHOD_NAME
44
- end
35
+ Sidekiq.lock_method = Sidekiq::Lock::METHOD_NAME
45
36
  end
46
37
 
47
38
  it 'allows container configuration' do
48
- begin
49
- container = CustomContainer.new
50
- Sidekiq.lock_container = container
39
+ container = CustomContainer.new
40
+ Sidekiq.lock_container = container
51
41
 
52
- class WorkerWithCustomContainer
53
- include Sidekiq::Worker
54
- include Sidekiq::Lock::Worker
55
- end
42
+ class WorkerWithCustomContainer
43
+ include Sidekiq::Worker
44
+ include Sidekiq::Lock::Worker
45
+ end
56
46
 
57
- container.store "lock-variable"
47
+ container.store "lock-variable"
58
48
 
59
- assert_equal "lock-variable", WorkerWithCustomContainer.new.lock
60
- ensure
61
- Sidekiq.lock_container = Sidekiq::Lock::Container.new
62
- end
49
+ assert_equal "lock-variable", WorkerWithCustomContainer.new.lock
50
+ ensure
51
+ Sidekiq.lock_container = Sidekiq::Lock::Container.new
63
52
  end
64
53
  end
65
54
  end
data/test/test_helper.rb CHANGED
@@ -1,13 +1,12 @@
1
1
  require 'minitest/autorun'
2
- require 'minitest/pride'
3
- require 'mocha/setup'
4
-
2
+ require 'mocha/minitest'
5
3
  require 'sidekiq'
6
4
  require 'test_workers'
7
5
 
8
6
  Sidekiq.logger.level = Logger::ERROR
9
7
 
10
- REDIS = Sidekiq::RedisConnection.create(url: 'redis://localhost/15')
8
+ REDIS_URL = ENV['REDIS_URL'] || 'redis://localhost/15'
9
+ REDIS = Sidekiq::RedisConnection.create(url: REDIS_URL)
11
10
 
12
11
  def redis(command, *args)
13
12
  Sidekiq.redis do |c|
data/test/test_workers.rb CHANGED
@@ -1,3 +1,4 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
1
2
  require 'sidekiq-lock'
2
3
 
3
4
  class LockWorker
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-lock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rafal Wojsznis
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-13 00:00:00.000000000 Z
11
+ date: 2024-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -16,112 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.14.0
19
+ version: '6'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 2.14.0
27
- - !ruby/object:Gem::Dependency
28
- name: redis
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 3.0.5
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: 3.0.5
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rack-test
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: mocha
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 0.14.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 0.14.0
97
- - !ruby/object:Gem::Dependency
98
- name: minitest
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: appraisal
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
26
+ version: '6'
125
27
  description: Simple redis-based lock mechanism for your sidekiq workers
126
28
  email:
127
29
  - rafal.wojsznis@gmail.com
@@ -153,7 +55,7 @@ homepage: https://github.com/emq/sidekiq-lock
153
55
  licenses:
154
56
  - MIT
155
57
  metadata: {}
156
- post_install_message:
58
+ post_install_message:
157
59
  rdoc_options: []
158
60
  require_paths:
159
61
  - lib
@@ -168,16 +70,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
70
  - !ruby/object:Gem::Version
169
71
  version: '0'
170
72
  requirements: []
171
- rubygems_version: 3.2.5
172
- signing_key:
73
+ rubygems_version: 3.4.10
74
+ signing_key:
173
75
  specification_version: 4
174
76
  summary: Simple redis-based lock mechanism for your sidekiq workers
175
77
  test_files:
176
- - test/test_workers.rb
177
- - test/lib/worker_test.rb
78
+ - test/lib/container_test.rb
79
+ - test/lib/lock_test.rb
80
+ - test/lib/middleware_test.rb
178
81
  - test/lib/redis_lock_test.rb
179
82
  - test/lib/testing/inline_test.rb
180
- - test/lib/middleware_test.rb
181
- - test/lib/lock_test.rb
182
- - test/lib/container_test.rb
83
+ - test/lib/worker_test.rb
183
84
  - test/test_helper.rb
85
+ - test/test_workers.rb