sidekiq-lock 0.7.0 → 0.8.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 +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +21 -16
- data/Rakefile +27 -0
- data/lib/sidekiq/lock/container.rb +2 -0
- data/lib/sidekiq/lock/middleware.rb +5 -0
- data/lib/sidekiq/lock/redis_lock.rb +23 -3
- data/lib/sidekiq/lock/testing/inline.rb +2 -0
- data/lib/sidekiq/lock/version.rb +3 -1
- data/lib/sidekiq/lock/worker.rb +2 -0
- data/lib/sidekiq/lock.rb +2 -0
- data/lib/sidekiq-lock.rb +2 -0
- data/test/lib/container_test.rb +2 -0
- data/test/lib/lock_test.rb +14 -17
- data/test/lib/middleware_test.rb +28 -5
- data/test/lib/redis_lock_test.rb +38 -5
- data/test/lib/testing/inline_test.rb +58 -8
- data/test/lib/worker_test.rb +2 -0
- data/test/test_helper.rb +2 -0
- data/test/test_workers.rb +16 -0
- metadata +10 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ffe149da064b8eb553518599979c7849039f092ced6b84189ff18fc58cc97ab
|
|
4
|
+
data.tar.gz: 830545455288f3f6ff5b2246670f81f6ca46bc67aaff5260ddb1c01e6910cf84
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 968ed503ca7b88e5d317c79193d21452b4390049cf4650319d6f13621a2c9d73feab068743564ff0e48f9b3770e89dbace35b6b46e8b0b650f19950a587e46f0
|
|
7
|
+
data.tar.gz: c947c37e1a96bc9a9160b8d7e0df7cb8c44f39a94ebb34140b9a35c6c5434c54de0e3377e042cc8af9d7305b9bad7948bea8d4d9e33c74ec5c75531d09ac01d0
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## 0.8.0 (September 1, 2026)
|
|
2
|
+
|
|
3
|
+
**NOTE:** Original author no longer uses this gem in production; changes are mostly: long-term maintenance, modern Sidekiq support and some edge cases handlers; if you noticed some breakage please do file an issue!
|
|
4
|
+
|
|
5
|
+
- added support for Sidekiq 8 and Ruby 3.1-3.5
|
|
6
|
+
- freeze all strings (performance)
|
|
7
|
+
- dropped support for Ruby versions older than 3.1
|
|
8
|
+
- clear the current lock before and after each middleware invocation, including when a worker raises
|
|
9
|
+
- validate that lock names are not empty and lock timeouts are positive integers
|
|
10
|
+
- prevent a lock instance that did not acquire a lock from releasing it
|
|
11
|
+
- fixed lock release when Redis has flushed its script cache
|
|
12
|
+
- updated inline testing guidance and corrected custom lock configuration examples
|
|
13
|
+
|
|
1
14
|
## 0.7.0 (Feb 7, 2024)
|
|
2
15
|
|
|
3
16
|
- support for Sidekiq 7.2 (thanks for the issue report [9mm](https://github.com/9mm))
|
data/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img width="
|
|
2
|
+
<img width="600" height="200" alt="sidekiq-lock" src="https://github.com/user-attachments/assets/443421d3-f508-464d-a505-d2ca6f18e21b" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
# Sidekiq::Lock
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
[](https://github.com/rwojsznis/sidekiq-lock/releases/latest)
|
|
9
|
+
[](https://github.com/rwojsznis/sidekiq-lock/actions/workflows/test.yml?query=branch%3Amain)
|
|
9
10
|
|
|
10
11
|
**Note:** This is a _complete_ piece of software, it should work across all future sidekiq & ruby versions.
|
|
11
12
|
|
|
@@ -98,9 +99,7 @@ class Worker
|
|
|
98
99
|
# I can do the work
|
|
99
100
|
# ...
|
|
100
101
|
ensure
|
|
101
|
-
# You probably want to manually release lock after work is done
|
|
102
|
-
# This method can be safely called even if lock wasn't acquired
|
|
103
|
-
# by current worker (thread). For more references see RedisLock class
|
|
102
|
+
# You probably want to manually release the lock after work is done.
|
|
104
103
|
lock.release!
|
|
105
104
|
end
|
|
106
105
|
else
|
|
@@ -114,18 +113,16 @@ Just be sure to provide valid redis key as a lock name.
|
|
|
114
113
|
|
|
115
114
|
### Customizing lock method name
|
|
116
115
|
|
|
117
|
-
You can change `lock` to something else
|
|
116
|
+
You can change `lock` to something else globally before starting Sidekiq:
|
|
118
117
|
|
|
119
118
|
``` ruby
|
|
120
|
-
Sidekiq.
|
|
121
|
-
config.lock_method = :redis_lock
|
|
122
|
-
end
|
|
119
|
+
Sidekiq.lock_method = :redis_lock
|
|
123
120
|
```
|
|
124
121
|
|
|
125
122
|
### Customizing lock _container_
|
|
126
123
|
|
|
127
124
|
If you would like to change default behavior of storing lock instance in `Thread.current` for whatever reason you
|
|
128
|
-
can do that as well
|
|
125
|
+
can do that as well before starting Sidekiq:
|
|
129
126
|
|
|
130
127
|
``` ruby
|
|
131
128
|
# Any thread-safe class that implements .fetch and .store methods will do
|
|
@@ -139,15 +136,23 @@ class CustomStorage
|
|
|
139
136
|
end
|
|
140
137
|
end
|
|
141
138
|
|
|
142
|
-
Sidekiq.
|
|
143
|
-
config.lock_container = CustomStorage.new
|
|
144
|
-
end
|
|
139
|
+
Sidekiq.lock_container = CustomStorage.new
|
|
145
140
|
```
|
|
146
141
|
|
|
147
142
|
### Inline testing
|
|
148
143
|
|
|
149
|
-
|
|
150
|
-
|
|
144
|
+
`perform_inline` invokes Sidekiq's normal server middleware chain. `Sidekiq::Testing.inline!`, however, uses a
|
|
145
|
+
separate testing middleware chain. Add the lock middleware to that chain if you want inline jobs to behave like
|
|
146
|
+
production jobs:
|
|
147
|
+
|
|
148
|
+
``` ruby
|
|
149
|
+
Sidekiq::Testing.server_middleware do |chain|
|
|
150
|
+
chain.add Sidekiq::Lock::Middleware
|
|
151
|
+
end
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
For tests that call `perform` directly, require `sidekiq/lock/testing/inline` in your test/spec helper to make these
|
|
155
|
+
manual setup and cleanup methods available:
|
|
151
156
|
|
|
152
157
|
- `set_sidekiq_lock(worker_class, payload)` - note: payload should be an array of worker arguments
|
|
153
158
|
- `clear_sidekiq_lock`
|
data/Rakefile
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env rake
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
2
4
|
require "bundler/gem_tasks"
|
|
5
|
+
require "fileutils"
|
|
3
6
|
require "rake/testtask"
|
|
7
|
+
require_relative "lib/sidekiq/lock/version"
|
|
4
8
|
|
|
5
9
|
task :default => :test
|
|
6
10
|
|
|
@@ -10,3 +14,26 @@ Rake::TestTask.new do |t|
|
|
|
10
14
|
t.test_files = FileList["test/**/*_test.rb"]
|
|
11
15
|
t.verbose = true
|
|
12
16
|
end
|
|
17
|
+
|
|
18
|
+
namespace :release do
|
|
19
|
+
desc "Validate the changelog entry for the current version"
|
|
20
|
+
task :check do
|
|
21
|
+
version = Sidekiq::Lock::VERSION
|
|
22
|
+
changelog = File.read("CHANGELOG.md")
|
|
23
|
+
heading = /^## #{Regexp.escape(version)} \([^)]+\)$/
|
|
24
|
+
entry = changelog.match(/#{heading.source}\n+(.*?)(?=^## |\z)/m)
|
|
25
|
+
|
|
26
|
+
abort "CHANGELOG.md has no entry for version #{version}" unless entry
|
|
27
|
+
abort "CHANGELOG.md entry for version #{version} is empty" if entry[1].strip.empty?
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
desc "Write GitHub release notes from the current changelog entry"
|
|
31
|
+
task notes: :check do
|
|
32
|
+
version = Sidekiq::Lock::VERSION
|
|
33
|
+
changelog = File.read("CHANGELOG.md")
|
|
34
|
+
entry = changelog.match(/^## #{Regexp.escape(version)} \([^)]+\)\n+(.*?)(?=^## |\z)/m)
|
|
35
|
+
|
|
36
|
+
FileUtils.mkdir_p("pkg")
|
|
37
|
+
File.write("pkg/release-notes.md", "#{entry[1].strip}\n")
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Sidekiq
|
|
2
4
|
module Lock
|
|
3
5
|
class Middleware
|
|
4
6
|
def call(worker, msg, _queue)
|
|
5
7
|
options = lock_options(worker)
|
|
8
|
+
Sidekiq.lock_container.store(nil)
|
|
6
9
|
setup_lock(options, msg['args']) unless options.nil?
|
|
7
10
|
|
|
8
11
|
yield
|
|
12
|
+
ensure
|
|
13
|
+
Sidekiq.lock_container.store(nil)
|
|
9
14
|
end
|
|
10
15
|
|
|
11
16
|
private
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'digest/sha1'
|
|
4
|
+
require 'securerandom'
|
|
5
|
+
|
|
1
6
|
module Sidekiq
|
|
2
7
|
module Lock
|
|
3
8
|
class RedisLock
|
|
@@ -32,6 +37,8 @@ module Sidekiq
|
|
|
32
37
|
end
|
|
33
38
|
|
|
34
39
|
def release!
|
|
40
|
+
return false unless acquired?
|
|
41
|
+
|
|
35
42
|
# even if lock expired / was take over by another process
|
|
36
43
|
# it still means from our perspective that we released it
|
|
37
44
|
@acquired = false
|
|
@@ -43,13 +50,26 @@ module Sidekiq
|
|
|
43
50
|
def name
|
|
44
51
|
raise ArgumentError, 'Provide a lock name inside sidekiq_options' if options[:name].nil?
|
|
45
52
|
|
|
46
|
-
@name ||=
|
|
53
|
+
@name ||= begin
|
|
54
|
+
name = options[:name].respond_to?(:call) ? options[:name].call(*payload) : options[:name]
|
|
55
|
+
raise ArgumentError, 'Lock name must not be empty' if name.nil? || name.to_s.empty?
|
|
56
|
+
|
|
57
|
+
name
|
|
58
|
+
end
|
|
47
59
|
end
|
|
48
60
|
|
|
49
61
|
def timeout
|
|
50
62
|
raise ArgumentError, 'Provide lock timeout inside sidekiq_options' if options[:timeout].nil?
|
|
51
63
|
|
|
52
|
-
@timeout ||=
|
|
64
|
+
@timeout ||= begin
|
|
65
|
+
timeout = options[:timeout].respond_to?(:call) ? options[:timeout].call(*payload) : options[:timeout]
|
|
66
|
+
timeout = Integer(timeout)
|
|
67
|
+
raise ArgumentError, 'Lock timeout must be positive' unless timeout.positive?
|
|
68
|
+
|
|
69
|
+
timeout
|
|
70
|
+
rescue TypeError, ArgumentError
|
|
71
|
+
raise ArgumentError, 'Lock timeout must be a positive integer'
|
|
72
|
+
end
|
|
53
73
|
end
|
|
54
74
|
|
|
55
75
|
private
|
|
@@ -63,7 +83,7 @@ module Sidekiq
|
|
|
63
83
|
begin
|
|
64
84
|
r.evalsha redis_lock_script_sha, [name], [value]
|
|
65
85
|
rescue RedisClient::CommandError
|
|
66
|
-
r.
|
|
86
|
+
r.call('EVAL', redis_lock_script, 1, name, value)
|
|
67
87
|
end
|
|
68
88
|
end
|
|
69
89
|
else
|
data/lib/sidekiq/lock/version.rb
CHANGED
data/lib/sidekiq/lock/worker.rb
CHANGED
data/lib/sidekiq/lock.rb
CHANGED
data/lib/sidekiq-lock.rb
CHANGED
data/test/lib/container_test.rb
CHANGED
data/test/lib/lock_test.rb
CHANGED
|
@@ -1,30 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
require 'open3'
|
|
3
5
|
|
|
4
6
|
module Sidekiq
|
|
5
7
|
describe Lock do
|
|
6
8
|
it 'automatically loads lock middleware for sidekiq server' do
|
|
7
|
-
|
|
9
|
+
script = <<~'RUBY'
|
|
10
|
+
require 'sidekiq/cli'
|
|
11
|
+
require 'sidekiq-lock'
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
chain = if Sidekiq.respond_to?(:default_configuration)
|
|
14
|
+
Sidekiq.default_configuration.server_middleware
|
|
15
|
+
else
|
|
16
|
+
Sidekiq.server_middleware
|
|
17
|
+
end
|
|
11
18
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
|
|
15
|
-
begin
|
|
16
|
-
Timeout.timeout(3) do
|
|
17
|
-
until stdout.eof? do
|
|
18
|
-
buffer_out << stdout.read_nonblock(16)
|
|
19
|
-
end
|
|
20
|
-
end
|
|
19
|
+
abort 'lock middleware was not registered' unless chain.exists?(Sidekiq::Lock::Middleware)
|
|
20
|
+
RUBY
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
Process.kill('KILL', thread.pid)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
22
|
+
_stdout, stderr, status = Open3.capture3(Gem.ruby, '-Ilib', '-e', script)
|
|
26
23
|
|
|
27
|
-
|
|
24
|
+
assert status.success?, stderr
|
|
28
25
|
end
|
|
29
26
|
end
|
|
30
27
|
end
|
data/test/lib/middleware_test.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module Sidekiq
|
|
@@ -18,20 +20,20 @@ module Sidekiq
|
|
|
18
20
|
it 'sets lock variable with provided static lock options' do
|
|
19
21
|
handler = Sidekiq::Lock::Middleware.new
|
|
20
22
|
handler.call(LockWorker.new, { 'class' => LockWorker, 'args' => [] }, 'default') do
|
|
21
|
-
|
|
23
|
+
assert_kind_of RedisLock, lock_container_variable
|
|
22
24
|
end
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
assert_nil lock_container_variable
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
it 'sets lock variable with provided dynamic options' do
|
|
28
30
|
handler = Sidekiq::Lock::Middleware.new
|
|
29
31
|
handler.call(DynamicLockWorker.new, { 'class' => DynamicLockWorker, 'args' => [1234, 1000] }, 'default') do
|
|
30
|
-
|
|
32
|
+
assert_equal "lock:1234", lock_container_variable.name
|
|
33
|
+
assert_equal 2000, lock_container_variable.timeout
|
|
31
34
|
end
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
assert_equal 2000, lock_container_variable.timeout
|
|
36
|
+
assert_nil lock_container_variable
|
|
35
37
|
end
|
|
36
38
|
|
|
37
39
|
it 'sets nothing for workers without lock options' do
|
|
@@ -42,6 +44,27 @@ module Sidekiq
|
|
|
42
44
|
|
|
43
45
|
assert_nil lock_container_variable
|
|
44
46
|
end
|
|
47
|
+
|
|
48
|
+
it 'clears a previous lock before running a worker without lock options' do
|
|
49
|
+
handler = Sidekiq::Lock::Middleware.new
|
|
50
|
+
set_lock_variable!(RedisLock.new({ 'timeout' => 500, 'name' => 'old-lock' }, []))
|
|
51
|
+
|
|
52
|
+
handler.call(RegularWorker.new, { 'class' => RegularWorker, 'args' => [] }, 'default') do
|
|
53
|
+
assert_nil lock_container_variable
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'clears the lock when a worker raises' do
|
|
58
|
+
handler = Sidekiq::Lock::Middleware.new
|
|
59
|
+
|
|
60
|
+
assert_raises RuntimeError do
|
|
61
|
+
handler.call(LockWorker.new, { 'class' => LockWorker, 'args' => [] }, 'default') do
|
|
62
|
+
raise 'worker failed'
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
assert_nil lock_container_variable
|
|
67
|
+
end
|
|
45
68
|
end
|
|
46
69
|
end
|
|
47
70
|
end
|
data/test/lib/redis_lock_test.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'test_helper'
|
|
2
4
|
|
|
3
5
|
module Sidekiq
|
|
@@ -36,6 +38,28 @@ module Sidekiq
|
|
|
36
38
|
assert RedisLock.new({ 'timeout' => 500, 'name' => 'lock-name' }, [])
|
|
37
39
|
end
|
|
38
40
|
|
|
41
|
+
it "rejects an empty evaluated name" do
|
|
42
|
+
error = assert_raises ArgumentError do
|
|
43
|
+
RedisLock.new({ 'timeout' => 500, 'name' => proc { nil } }, [])
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
assert_equal 'Lock name must not be empty', error.message
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "rejects invalid evaluated timeouts" do
|
|
50
|
+
[nil, 'invalid', 0, -1].each do |timeout|
|
|
51
|
+
assert_raises ArgumentError do
|
|
52
|
+
RedisLock.new({ 'timeout' => proc { timeout }, 'name' => 'lock-name' }, [])
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "accepts a positive integer timeout encoded as a string" do
|
|
58
|
+
lock = RedisLock.new({ 'timeout' => '500', 'name' => 'lock-name' }, [])
|
|
59
|
+
|
|
60
|
+
assert_equal 500, lock.timeout
|
|
61
|
+
end
|
|
62
|
+
|
|
39
63
|
it "is released by default" do
|
|
40
64
|
lock = RedisLock.new({ 'timeout' => 500, 'name' => 'lock-name' }, [])
|
|
41
65
|
refute lock.acquired?
|
|
@@ -60,18 +84,18 @@ module Sidekiq
|
|
|
60
84
|
assert lock.acquire!
|
|
61
85
|
end
|
|
62
86
|
|
|
63
|
-
it "
|
|
87
|
+
it "releases a lock after Redis flushes its script cache" do
|
|
64
88
|
lock = RedisLock.new({'timeout' => 1000, 'name' => 'test-lock', 'value' => 'lock value'}, [])
|
|
65
89
|
assert lock.acquire!
|
|
66
90
|
assert_equal 'lock value', redis("get", lock.name)
|
|
67
91
|
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
92
|
|
|
72
|
-
redis("script", "flush")
|
|
73
93
|
assert lock.acquire!
|
|
74
94
|
assert_equal 'lock value', redis("get", lock.name)
|
|
95
|
+
redis("script", "flush")
|
|
96
|
+
|
|
97
|
+
assert lock.release!
|
|
98
|
+
assert_nil redis("get", lock.name)
|
|
75
99
|
end
|
|
76
100
|
|
|
77
101
|
it "cannot acquire lock if it's already taken by other process/thread" do
|
|
@@ -82,6 +106,15 @@ module Sidekiq
|
|
|
82
106
|
refute slower_lock.acquire!
|
|
83
107
|
end
|
|
84
108
|
|
|
109
|
+
it "does not release a lock that this instance did not acquire" do
|
|
110
|
+
acquired_lock = RedisLock.new({'timeout' => 1000, 'name' => 'test-lock', 'value' => 'shared'}, [])
|
|
111
|
+
unacquired_lock = RedisLock.new({'timeout' => 1000, 'name' => 'test-lock', 'value' => 'shared'}, [])
|
|
112
|
+
assert acquired_lock.acquire!
|
|
113
|
+
|
|
114
|
+
refute unacquired_lock.release!
|
|
115
|
+
assert_equal 'shared', redis('get', 'test-lock')
|
|
116
|
+
end
|
|
117
|
+
|
|
85
118
|
it "releases taken lock" do
|
|
86
119
|
lock = RedisLock.new({'timeout' => 100, 'name' => 'test-lock'}, [])
|
|
87
120
|
lock.acquire!
|
|
@@ -1,24 +1,74 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require "test_helper"
|
|
2
4
|
require "sidekiq/lock/testing/inline"
|
|
3
5
|
|
|
6
|
+
if Sidekiq.respond_to?(:testing!)
|
|
7
|
+
Sidekiq.testing!(:fake)
|
|
8
|
+
else
|
|
9
|
+
require "sidekiq/testing"
|
|
10
|
+
end
|
|
11
|
+
|
|
4
12
|
describe "inline test helper" do
|
|
5
13
|
after { reset_lock_variable! }
|
|
6
14
|
|
|
7
|
-
it "has helper
|
|
8
|
-
|
|
9
|
-
.expects(:new)
|
|
10
|
-
.with({ timeout: 1, name: 'lock-worker' }, 'worker argument')
|
|
11
|
-
.returns('lock set')
|
|
15
|
+
it "has helper function for setting lock" do
|
|
16
|
+
set_sidekiq_lock(LockWorker, ['worker argument'])
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
assert_equal 'lock
|
|
18
|
+
assert_kind_of Sidekiq::Lock::RedisLock, lock_container_variable
|
|
19
|
+
assert_equal 'lock-worker', lock_container_variable.name
|
|
20
|
+
assert_equal 1, lock_container_variable.timeout
|
|
15
21
|
end
|
|
16
22
|
|
|
17
|
-
it "
|
|
23
|
+
it "provides a manually configured lock to a directly executed worker" do
|
|
24
|
+
set_sidekiq_lock(InlineLockWorker, ['manual'])
|
|
25
|
+
|
|
26
|
+
InlineLockWorker.new.perform('manual')
|
|
27
|
+
|
|
28
|
+
assert_equal ['inline-lock-manual', 1000], InlineLockWorker.observed_lock
|
|
29
|
+
ensure
|
|
30
|
+
InlineLockWorker.observed_lock = nil
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "has helper function for clearing lock" do
|
|
18
34
|
set_lock_variable! "test"
|
|
19
35
|
assert_equal "test", lock_container_variable
|
|
20
36
|
|
|
21
37
|
clear_sidekiq_lock
|
|
22
38
|
assert_nil lock_container_variable
|
|
23
39
|
end
|
|
40
|
+
|
|
41
|
+
it "provides the lock during perform_inline" do
|
|
42
|
+
skip 'perform_inline is unavailable in this Sidekiq version' unless InlineLockWorker.respond_to?(:perform_inline)
|
|
43
|
+
|
|
44
|
+
chain = Sidekiq.default_configuration.server_middleware
|
|
45
|
+
middleware_added = !chain.exists?(Sidekiq::Lock::Middleware)
|
|
46
|
+
chain.add Sidekiq::Lock::Middleware if middleware_added
|
|
47
|
+
|
|
48
|
+
InlineLockWorker.perform_inline('direct')
|
|
49
|
+
|
|
50
|
+
assert_equal ['inline-lock-direct', 1000], InlineLockWorker.observed_lock
|
|
51
|
+
assert_nil lock_container_variable
|
|
52
|
+
ensure
|
|
53
|
+
chain&.remove(Sidekiq::Lock::Middleware) if middleware_added
|
|
54
|
+
InlineLockWorker.observed_lock = nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it "provides the lock during Sidekiq testing inline execution" do
|
|
58
|
+
Sidekiq::Testing.server_middleware do |chain|
|
|
59
|
+
chain.add Sidekiq::Lock::Middleware unless chain.exists?(Sidekiq::Lock::Middleware)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
Sidekiq::Testing.inline! do
|
|
63
|
+
InlineLockWorker.perform_async('testing')
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
assert_equal ['inline-lock-testing', 1000], InlineLockWorker.observed_lock
|
|
67
|
+
assert_nil lock_container_variable
|
|
68
|
+
ensure
|
|
69
|
+
Sidekiq::Testing.server_middleware do |chain|
|
|
70
|
+
chain.remove(Sidekiq::Lock::Middleware)
|
|
71
|
+
end
|
|
72
|
+
InlineLockWorker.observed_lock = nil
|
|
73
|
+
end
|
|
24
74
|
end
|
data/test/lib/worker_test.rb
CHANGED
data/test/test_helper.rb
CHANGED
data/test/test_workers.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
|
2
4
|
require 'sidekiq-lock'
|
|
3
5
|
|
|
@@ -20,3 +22,17 @@ class RegularWorker
|
|
|
20
22
|
include Sidekiq::Worker
|
|
21
23
|
include Sidekiq::Lock::Worker
|
|
22
24
|
end
|
|
25
|
+
|
|
26
|
+
class InlineLockWorker
|
|
27
|
+
include Sidekiq::Worker
|
|
28
|
+
include Sidekiq::Lock::Worker
|
|
29
|
+
sidekiq_options lock: { timeout: 1000, name: proc { |argument| "inline-lock-#{argument}" } }
|
|
30
|
+
|
|
31
|
+
class << self
|
|
32
|
+
attr_accessor :observed_lock
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def perform(argument)
|
|
36
|
+
self.class.observed_lock = [lock.name, lock.timeout]
|
|
37
|
+
end
|
|
38
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sidekiq-lock
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Rafal Wojsznis
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: sidekiq
|
|
@@ -51,11 +50,14 @@ files:
|
|
|
51
50
|
- test/lib/worker_test.rb
|
|
52
51
|
- test/test_helper.rb
|
|
53
52
|
- test/test_workers.rb
|
|
54
|
-
homepage: https://github.com/
|
|
53
|
+
homepage: https://github.com/rwojsznis/sidekiq-lock
|
|
55
54
|
licenses:
|
|
56
55
|
- MIT
|
|
57
|
-
metadata:
|
|
58
|
-
|
|
56
|
+
metadata:
|
|
57
|
+
bug_tracker_uri: https://github.com/rwojsznis/sidekiq-lock/issues
|
|
58
|
+
changelog_uri: https://github.com/rwojsznis/sidekiq-lock/blob/main/CHANGELOG.md
|
|
59
|
+
source_code_uri: https://github.com/rwojsznis/sidekiq-lock
|
|
60
|
+
rubygems_mfa_required: 'true'
|
|
59
61
|
rdoc_options: []
|
|
60
62
|
require_paths:
|
|
61
63
|
- lib
|
|
@@ -63,15 +65,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
63
65
|
requirements:
|
|
64
66
|
- - ">="
|
|
65
67
|
- !ruby/object:Gem::Version
|
|
66
|
-
version: '
|
|
68
|
+
version: '3.1'
|
|
67
69
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
68
70
|
requirements:
|
|
69
71
|
- - ">="
|
|
70
72
|
- !ruby/object:Gem::Version
|
|
71
73
|
version: '0'
|
|
72
74
|
requirements: []
|
|
73
|
-
rubygems_version:
|
|
74
|
-
signing_key:
|
|
75
|
+
rubygems_version: 4.0.16
|
|
75
76
|
specification_version: 4
|
|
76
77
|
summary: Simple redis-based lock mechanism for your sidekiq workers
|
|
77
78
|
test_files:
|