sidekiq-lock 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 94c0d6993d3e6f8c2acd6a63e2e78464ac974369138f6c20eeb91525d0b5ea13
4
- data.tar.gz: 75437ca38c53bc825d0e6e77b8dc2ef64c5c42bb8802746f5fbacf1f91c9e4f5
3
+ metadata.gz: 1ffe149da064b8eb553518599979c7849039f092ced6b84189ff18fc58cc97ab
4
+ data.tar.gz: 830545455288f3f6ff5b2246670f81f6ca46bc67aaff5260ddb1c01e6910cf84
5
5
  SHA512:
6
- metadata.gz: 463adf7d4dbf5d468a1c795105a716d94fd6f77141e7c7f3d77a84076e4e222cc2b6fb57f64d5286bca6fc8b9491c4de891190fb3d255f1766acd879253220d0
7
- data.tar.gz: c215cce1d79e99aaa28a04a5238aac165a8e5d36271a372b39067a80040109e5f64117114fdbfae227c5cb406f86cd46e554cfa6820978573abd1f08b04ada6d
6
+ metadata.gz: 968ed503ca7b88e5d317c79193d21452b4390049cf4650319d6f13621a2c9d73feab068743564ff0e48f9b3770e89dbace35b6b46e8b0b650f19950a587e46f0
7
+ data.tar.gz: c947c37e1a96bc9a9160b8d7e0df7cb8c44f39a94ebb34140b9a35c6c5434c54de0e3377e042cc8af9d7305b9bad7948bea8d4d9e33c74ec5c75531d09ac01d0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
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
+
14
+ ## 0.7.0 (Feb 7, 2024)
15
+
16
+ - support for Sidekiq 7.2 (thanks for the issue report [9mm](https://github.com/9mm))
17
+ - dropped support for Sidekiq 5 and older [as it reached EOL](https://github.com/sidekiq/sidekiq/wiki/Commercial-Support#version-policy)
18
+ - removed `redis` as gem dependency (relying on sidekiq version you're using to choose the right one)
19
+
1
20
  ## 0.6.0 (May 27, 2023)
2
21
 
3
22
  - support for Sidekiq 7 (thanks to [@stympy](https://github.com/stympy))
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,12 @@
1
1
  <p align="center">
2
- <img width="300" height="210" src="https://github.com/rwojsznis/sidekiq-lock/raw/main/logo.png">
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
- [![Code Climate](https://codeclimate.com/github/rwojsznis/sidekiq-lock.png)](https://codeclimate.com/github/rwojsznis/sidekiq-lock)
8
- [![Gem Version](https://badge.fury.io/rb/sidekiq-lock.png)](http://badge.fury.io/rb/sidekiq-lock)
7
+
8
+ [![GitHub Release](https://img.shields.io/github/v/release/rwojsznis/sidekiq-lock)](https://github.com/rwojsznis/sidekiq-lock/releases/latest)
9
+ [![CI](https://github.com/rwojsznis/sidekiq-lock/actions/workflows/test.yml/badge.svg?branch=main)](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
 
@@ -18,7 +19,7 @@ time - it provides a `lock` method that you can use in whatever way you want.
18
19
 
19
20
  This gem requires at least:
20
21
  - redis 2.6.12
21
- - redis-rb 3.0.5 (support for extended SET method)
22
+ - sidekiq 6
22
23
 
23
24
  Add this line to your application's Gemfile:
24
25
 
@@ -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 (globally) in sidekiq server configuration:
116
+ You can change `lock` to something else globally before starting Sidekiq:
118
117
 
119
118
  ``` ruby
120
- Sidekiq.configure_server do |config|
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 via server configuration:
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.configure_server do |config|
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
- As you know middleware is not invoked when testing jobs inline, you can require in your test/spec helper file
150
- `sidekiq/lock/testing/inline` to include two methods that will help you setting / clearing up lock manually:
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,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sidekiq
2
4
  module Lock
3
5
  class Container
@@ -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
@@ -23,11 +28,17 @@ module Sidekiq
23
28
  # this also requires redis-rb >= 3.0.5
24
29
  def acquire!
25
30
  @acquired ||= Sidekiq.redis do |r|
26
- r.set(name, value, nx: true, px: timeout)
31
+ if Sidekiq::VERSION >= '7.2'
32
+ r.set(name, value, 'nx', 'px', timeout)
33
+ else
34
+ r.set(name, value, nx: true, px: timeout)
35
+ end
27
36
  end
28
37
  end
29
38
 
30
39
  def release!
40
+ return false unless acquired?
41
+
31
42
  # even if lock expired / was take over by another process
32
43
  # it still means from our perspective that we released it
33
44
  @acquired = false
@@ -39,13 +50,26 @@ module Sidekiq
39
50
  def name
40
51
  raise ArgumentError, 'Provide a lock name inside sidekiq_options' if options[:name].nil?
41
52
 
42
- @name ||= (options[:name].respond_to?(:call) ? options[:name].call(*payload) : options[: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
43
59
  end
44
60
 
45
61
  def timeout
46
62
  raise ArgumentError, 'Provide lock timeout inside sidekiq_options' if options[:timeout].nil?
47
63
 
48
- @timeout ||= (options[:timeout].respond_to?(:call) ? options[:timeout].call(*payload) : options[:timeout]).to_i
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
49
73
  end
50
74
 
51
75
  private
@@ -59,7 +83,7 @@ module Sidekiq
59
83
  begin
60
84
  r.evalsha redis_lock_script_sha, [name], [value]
61
85
  rescue RedisClient::CommandError
62
- r.eval redis_lock_script, 1, [name], [value]
86
+ r.call('EVAL', redis_lock_script, 1, name, value)
63
87
  end
64
88
  end
65
89
  else
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  def set_sidekiq_lock(worker_class, payload)
2
4
  options = worker_class.get_sidekiq_options['lock']
3
5
  Sidekiq.lock_container.store(Sidekiq::Lock::RedisLock.new(options, payload))
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sidekiq
2
4
  module Lock
3
- VERSION = '0.6.0'
5
+ VERSION = '0.8.0'
4
6
  end
5
7
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Sidekiq
2
4
  module Lock
3
5
  module Worker
data/lib/sidekiq/lock.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sidekiq/lock/container'
2
4
  require 'sidekiq/lock/middleware'
3
5
  require 'sidekiq/lock/redis_lock'
data/lib/sidekiq-lock.rb CHANGED
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'sidekiq/lock'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
  require 'open3'
3
5
 
@@ -1,29 +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
- skip 'Sidekiq 7+ does not print out middleware information' if Sidekiq::VERSION >= '7'
8
-
9
- cmd = 'sidekiq -r ./test/test_workers.rb -v'
10
- buffer = ''
9
+ script = <<~'RUBY'
10
+ require 'sidekiq/cli'
11
+ require 'sidekiq-lock'
11
12
 
12
- # very not fancy (https://78.media.tumblr.com/tumblr_lzkpw7DAl21qhy6c9o2_400.gif)
13
- # solution, but should do the job
14
- Open3.popen3(cmd) do |stdin, stdout, stderr, thread|
15
- begin
16
- Timeout.timeout(5) do
17
- until stdout.eof? do
18
- buffer << stdout.read_nonblock(16)
19
- end
20
- end
21
- rescue Timeout::Error
22
- Process.kill('KILL', thread.pid)
13
+ chain = if Sidekiq.respond_to?(:default_configuration)
14
+ Sidekiq.default_configuration.server_middleware
15
+ else
16
+ Sidekiq.server_middleware
23
17
  end
24
- end
25
18
 
26
- assert_match(/\s?Middleware:.*Sidekiq::Lock::Middleware/i, buffer)
19
+ abort 'lock middleware was not registered' unless chain.exists?(Sidekiq::Lock::Middleware)
20
+ RUBY
21
+
22
+ _stdout, stderr, status = Open3.capture3(Gem.ruby, '-Ilib', '-e', script)
23
+
24
+ assert status.success?, stderr
27
25
  end
28
26
  end
29
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module Sidekiq
@@ -15,32 +17,54 @@ module Sidekiq
15
17
  reset_lock_variable!
16
18
  end
17
19
 
18
- let(:handler) { Sidekiq::Lock::Middleware.new }
19
-
20
20
  it 'sets lock variable with provided static lock options' do
21
+ handler = Sidekiq::Lock::Middleware.new
21
22
  handler.call(LockWorker.new, { 'class' => LockWorker, 'args' => [] }, 'default') do
22
- true
23
+ assert_kind_of RedisLock, lock_container_variable
23
24
  end
24
25
 
25
- assert_kind_of RedisLock, lock_container_variable
26
+ assert_nil lock_container_variable
26
27
  end
27
28
 
28
29
  it 'sets lock variable with provided dynamic options' do
30
+ handler = Sidekiq::Lock::Middleware.new
29
31
  handler.call(DynamicLockWorker.new, { 'class' => DynamicLockWorker, 'args' => [1234, 1000] }, 'default') do
30
- true
32
+ assert_equal "lock:1234", lock_container_variable.name
33
+ assert_equal 2000, lock_container_variable.timeout
31
34
  end
32
35
 
33
- assert_equal "lock:1234", lock_container_variable.name
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
40
+ handler = Sidekiq::Lock::Middleware.new
38
41
  handler.call(RegularWorker.new, { 'class' => RegularWorker, 'args' => [] }, 'default') do
39
42
  true
40
43
  end
41
44
 
42
45
  assert_nil lock_container_variable
43
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
44
68
  end
45
69
  end
46
70
  end
@@ -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 "sets proper lock value on first and second acquire" do
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 fuction for setting lock" do
8
- Sidekiq::Lock::RedisLock
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
- set_sidekiq_lock(LockWorker, 'worker argument')
14
- assert_equal 'lock set', lock_container_variable
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 "has helper fuction for clearing lock" do
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
@@ -1,10 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  module Sidekiq
4
6
  module Lock
5
7
  describe Worker do
6
- # after { }
7
-
8
8
  class CustomContainer
9
9
  def initialize
10
10
  @lock = nil
@@ -19,47 +19,38 @@ module Sidekiq
19
19
  end
20
20
  end
21
21
 
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
22
  it 'allows method name configuration' do
28
- begin
29
- Sidekiq.lock_method = :custom_lock_name
23
+ Sidekiq.lock_method = :custom_lock_name
30
24
 
31
- class WorkerWithCustomLockName
32
- include Sidekiq::Worker
33
- include Sidekiq::Lock::Worker
34
- end
25
+ class WorkerWithCustomLockName
26
+ include Sidekiq::Worker
27
+ include Sidekiq::Lock::Worker
28
+ end
35
29
 
36
- set_lock_variable! "custom_name"
30
+ set_lock_variable! "custom_name"
37
31
 
38
- assert_equal "custom_name", WorkerWithCustomLockName.new.custom_lock_name
32
+ assert_equal "custom_name", WorkerWithCustomLockName.new.custom_lock_name
39
33
 
40
- reset_lock_variable!
41
- ensure
34
+ reset_lock_variable!
35
+ ensure
42
36
 
43
- Sidekiq.lock_method = Sidekiq::Lock::METHOD_NAME
44
- end
37
+ Sidekiq.lock_method = Sidekiq::Lock::METHOD_NAME
45
38
  end
46
39
 
47
40
  it 'allows container configuration' do
48
- begin
49
- container = CustomContainer.new
50
- Sidekiq.lock_container = container
41
+ container = CustomContainer.new
42
+ Sidekiq.lock_container = container
51
43
 
52
- class WorkerWithCustomContainer
53
- include Sidekiq::Worker
54
- include Sidekiq::Lock::Worker
55
- end
44
+ class WorkerWithCustomContainer
45
+ include Sidekiq::Worker
46
+ include Sidekiq::Lock::Worker
47
+ end
56
48
 
57
- container.store "lock-variable"
49
+ container.store "lock-variable"
58
50
 
59
- assert_equal "lock-variable", WorkerWithCustomContainer.new.lock
60
- ensure
61
- Sidekiq.lock_container = Sidekiq::Lock::Container.new
62
- end
51
+ assert_equal "lock-variable", WorkerWithCustomContainer.new.lock
52
+ ensure
53
+ Sidekiq.lock_container = Sidekiq::Lock::Container.new
63
54
  end
64
55
  end
65
56
  end
data/test/test_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
- require 'minitest/autorun'
2
- require 'minitest/pride'
3
- require 'mocha/setup'
1
+ # frozen_string_literal: true
4
2
 
3
+ require 'minitest/autorun'
4
+ require 'mocha/minitest'
5
5
  require 'sidekiq'
6
6
  require 'test_workers'
7
7
 
data/test/test_workers.rb CHANGED
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
1
4
  require 'sidekiq-lock'
2
5
 
3
6
  class LockWorker
@@ -19,3 +22,17 @@ class RegularWorker
19
22
  include Sidekiq::Worker
20
23
  include Sidekiq::Lock::Worker
21
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.6.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: 2023-05-27 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: sidekiq
@@ -16,98 +15,14 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: 2.14.0
18
+ version: '6'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !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: mocha
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 0.14.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.14.0
83
- - !ruby/object:Gem::Dependency
84
- name: minitest
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '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'
97
- - !ruby/object:Gem::Dependency
98
- name: appraisal
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'
25
+ version: '6'
111
26
  description: Simple redis-based lock mechanism for your sidekiq workers
112
27
  email:
113
28
  - rafal.wojsznis@gmail.com
@@ -135,11 +50,14 @@ files:
135
50
  - test/lib/worker_test.rb
136
51
  - test/test_helper.rb
137
52
  - test/test_workers.rb
138
- homepage: https://github.com/emq/sidekiq-lock
53
+ homepage: https://github.com/rwojsznis/sidekiq-lock
139
54
  licenses:
140
55
  - MIT
141
- metadata: {}
142
- post_install_message:
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'
143
61
  rdoc_options: []
144
62
  require_paths:
145
63
  - lib
@@ -147,15 +65,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
147
65
  requirements:
148
66
  - - ">="
149
67
  - !ruby/object:Gem::Version
150
- version: '0'
68
+ version: '3.1'
151
69
  required_rubygems_version: !ruby/object:Gem::Requirement
152
70
  requirements:
153
71
  - - ">="
154
72
  - !ruby/object:Gem::Version
155
73
  version: '0'
156
74
  requirements: []
157
- rubygems_version: 3.3.7
158
- signing_key:
75
+ rubygems_version: 4.0.16
159
76
  specification_version: 4
160
77
  summary: Simple redis-based lock mechanism for your sidekiq workers
161
78
  test_files: