sidekiq-lock 0.0.1
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.
- data/.gitignore +20 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +102 -0
- data/Rakefile +12 -0
- data/lib/sidekiq-lock.rb +1 -0
- data/lib/sidekiq/lock.rb +16 -0
- data/lib/sidekiq/lock/middleware.rb +24 -0
- data/lib/sidekiq/lock/redis_lock.rb +72 -0
- data/lib/sidekiq/lock/version.rb +5 -0
- data/lib/sidekiq/lock/worker.rb +11 -0
- data/sidekiq-lock.gemspec +26 -0
- data/test/lib/middleware_test.rb +67 -0
- data/test/lib/redis_lock_test.rb +84 -0
- data/test/lib/worker_test.rb +14 -0
- data/test/test_helper.rb +18 -0
- metadata +154 -0
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Rafal Wojsznis
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
# Sidekiq::Lock
|
2
|
+
|
3
|
+
[](https://codeclimate.com/github/emq/sidekiq-lock)
|
4
|
+
[](https://travis-ci.org/emq/sidekiq-lock)
|
5
|
+
|
6
|
+
Redis-based simple locking mechanism for [sidekiq][2]. Uses [SET command][1] introduced in Redis 2.6.16.
|
7
|
+
|
8
|
+
It can be handy if you push a lot of jobs into the queue(s), but you don't want to execute specific jobs at the same time - it provides a `lock` method that you can use in whatever way you want.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
|
12
|
+
This gem requires at least:
|
13
|
+
- redis 2.6.12
|
14
|
+
- redis-rb 3.0.5 (support for extended SET method)
|
15
|
+
|
16
|
+
Add this line to your application's Gemfile:
|
17
|
+
|
18
|
+
``` ruby
|
19
|
+
gem 'sidekiq-lock'
|
20
|
+
```
|
21
|
+
|
22
|
+
And then execute:
|
23
|
+
|
24
|
+
``` bash
|
25
|
+
$ bundle
|
26
|
+
```
|
27
|
+
|
28
|
+
## Usage
|
29
|
+
|
30
|
+
Sidekiq-lock is a middleware/module combination, let me go through my thought process here :).
|
31
|
+
|
32
|
+
In your worker class include `Sidekiq::Lock::Worker` module and provide `lock` attribute inside `sidekiq_options`, for example:
|
33
|
+
|
34
|
+
``` ruby
|
35
|
+
class Worker
|
36
|
+
include Sidekiq::Worker
|
37
|
+
include Sidekiq::Lock::Worker
|
38
|
+
|
39
|
+
# static lock that expires after one second
|
40
|
+
sidekiq_options lock: { timeout: 1000, name: 'lock-worker' }
|
41
|
+
|
42
|
+
def perform
|
43
|
+
# ...
|
44
|
+
end
|
45
|
+
end
|
46
|
+
```
|
47
|
+
|
48
|
+
What will happen is:
|
49
|
+
|
50
|
+
- middleware will setup a `Sidekiq::Lock::RedisLock` object under `Thread.current[Sidekiq::Lock::THREAD_KEY]` (well, I had no better idea for this) - assuming you provided `lock` options, otherwise it will do nothing, just execute your worker's code
|
51
|
+
|
52
|
+
- `Sidekiq::Lock::Worker` module provides a `lock` method that just simply points to that thread variable, just as a convenience
|
53
|
+
|
54
|
+
So now in your worker class you can call (whenever you need):
|
55
|
+
|
56
|
+
- `lock.acquire!` - will try to acquire the lock, if returns false on failure (that means some other process / thread took the lock first)
|
57
|
+
- `lock.acquired?` - set to `true` when lock is successfully acquired
|
58
|
+
- `lock.release!` - deletes the lock (if not already expired / taken by another process)
|
59
|
+
|
60
|
+
### Lock options
|
61
|
+
|
62
|
+
sidekiq_options lock will accept static values or `Proc` that will be called on argument(s) passed to `perform` method.
|
63
|
+
|
64
|
+
- timeout - specified expire time, in milliseconds
|
65
|
+
- name - name of the redis key that will be used as lock name
|
66
|
+
|
67
|
+
Dynamic lock example:
|
68
|
+
|
69
|
+
``` ruby
|
70
|
+
class Worker
|
71
|
+
include Sidekiq::Worker
|
72
|
+
include Sidekiq::Lock::Worker
|
73
|
+
sidekiq_options lock: {
|
74
|
+
timeout: proc { |user_id, timeout| timeout * 2 },
|
75
|
+
name: proc { |user_id, timeout| "lock:peruser:#{user_id}" }
|
76
|
+
}
|
77
|
+
|
78
|
+
def perform(user_id, timeout)
|
79
|
+
# ...
|
80
|
+
# do some work
|
81
|
+
# only at this point I want to acquire the lock
|
82
|
+
if lock.acquire!
|
83
|
+
# I can do the work
|
84
|
+
else
|
85
|
+
# reschedule, raise an error or do whatever you want
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
Just be sure to provide valid redis key as a lock name.
|
92
|
+
|
93
|
+
## Contributing
|
94
|
+
|
95
|
+
1. Fork it
|
96
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
97
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
98
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
99
|
+
5. Create new Pull Request
|
100
|
+
|
101
|
+
[1]: http://redis.io/commands/set
|
102
|
+
[2]: https://github.com/mperham/sidekiq
|
data/Rakefile
ADDED
data/lib/sidekiq-lock.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'sidekiq/lock'
|
data/lib/sidekiq/lock.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "sidekiq/lock/version"
|
2
|
+
require "sidekiq/lock/worker"
|
3
|
+
require "sidekiq/lock/middleware"
|
4
|
+
require "sidekiq/lock/redis_lock"
|
5
|
+
|
6
|
+
module Sidekiq
|
7
|
+
module Lock
|
8
|
+
THREAD_KEY = :sidekiq_lock
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
Sidekiq.configure_server do |config|
|
13
|
+
config.server_middleware do |chain|
|
14
|
+
chain.add Sidekiq::Lock::Middleware
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Lock
|
3
|
+
class Middleware
|
4
|
+
|
5
|
+
def call(worker, msg, queue)
|
6
|
+
options = lock_options(worker)
|
7
|
+
setup_lock(options, msg['args']) unless options.nil?
|
8
|
+
|
9
|
+
yield
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def setup_lock(options, payload)
|
15
|
+
Thread.current[Sidekiq::Lock::THREAD_KEY] = RedisLock.new(options, payload)
|
16
|
+
end
|
17
|
+
|
18
|
+
def lock_options(worker)
|
19
|
+
worker.class.get_sidekiq_options['lock']
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Sidekiq
|
2
|
+
module Lock
|
3
|
+
class RedisLock
|
4
|
+
attr_reader :options, :payload
|
5
|
+
|
6
|
+
# checks for configuration
|
7
|
+
def initialize(options, payload)
|
8
|
+
@options = options.symbolize_keys
|
9
|
+
@payload = payload
|
10
|
+
@acquired = false
|
11
|
+
|
12
|
+
timeout
|
13
|
+
name
|
14
|
+
end
|
15
|
+
|
16
|
+
def acquired?
|
17
|
+
@acquired
|
18
|
+
end
|
19
|
+
|
20
|
+
# acquire lock using modified SET command introduced in Redis 2.6.12
|
21
|
+
# this also requires redis-rb >= 3.0.5
|
22
|
+
def acquire!
|
23
|
+
@acquired ||= Sidekiq.redis do |r|
|
24
|
+
r.set(name, value, { nx: true, px: timeout })
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def release!
|
29
|
+
Sidekiq.redis do |r|
|
30
|
+
begin
|
31
|
+
r.evalsha redis_lock_script_sha, keys: [name], argv: [value]
|
32
|
+
rescue Redis::CommandError
|
33
|
+
r.eval redis_lock_script, keys: [name], argv: [value]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def name
|
39
|
+
raise ArgumentError, "Provide a lock name inside sidekiq_options" if options[:name].nil?
|
40
|
+
|
41
|
+
@name ||= (options[:name].respond_to?(:call) ? options[:name].call(*payload) : options[:name])
|
42
|
+
end
|
43
|
+
|
44
|
+
def timeout
|
45
|
+
raise ArgumentError, "Provide lock timeout inside sidekiq_options" if options[:timeout].nil?
|
46
|
+
|
47
|
+
@timeout ||= (options[:timeout].respond_to?(:call) ? options[:timeout].call(*payload) : options[:timeout]).to_i
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def redis_lock_script_sha
|
53
|
+
@lock_script_sha ||= Digest::SHA1.hexdigest redis_lock_script
|
54
|
+
end
|
55
|
+
|
56
|
+
def redis_lock_script
|
57
|
+
<<-LUA
|
58
|
+
if redis.call("get", KEYS[1]) == ARGV[1]
|
59
|
+
then
|
60
|
+
return redis.call("del",KEYS[1])
|
61
|
+
else
|
62
|
+
return 0
|
63
|
+
end
|
64
|
+
LUA
|
65
|
+
end
|
66
|
+
|
67
|
+
def value
|
68
|
+
@value ||= SecureRandom.hex(25)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sidekiq/lock/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sidekiq-lock"
|
8
|
+
spec.version = Sidekiq::Lock::VERSION
|
9
|
+
spec.authors = ["Rafal Wojsznis"]
|
10
|
+
spec.email = ["rafal.wojsznis@gmail.com"]
|
11
|
+
spec.description = spec.summary = "Simple redis-based lock mechanism for your sidekiq workers"
|
12
|
+
spec.homepage = "https://github.com/emq/sidekiq-lock"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_dependency "sidekiq", ">= 2.14.0"
|
21
|
+
spec.add_dependency "redis", ">= 3.0.5"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "rack-test"
|
26
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
class LockWorker
|
4
|
+
include Sidekiq::Worker
|
5
|
+
include Sidekiq::Lock::Worker
|
6
|
+
sidekiq_options lock: { timeout: 1, name: 'lock-worker' }
|
7
|
+
end
|
8
|
+
|
9
|
+
class DynamicLockWorker
|
10
|
+
include Sidekiq::Worker
|
11
|
+
include Sidekiq::Lock::Worker
|
12
|
+
sidekiq_options lock: {
|
13
|
+
timeout: proc { |user_id, timeout| timeout*2 },
|
14
|
+
name: proc { |user_id, timeout| "lock:#{user_id}" }
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
class RegularWorker
|
19
|
+
include Sidekiq::Worker
|
20
|
+
include Sidekiq::Lock::Worker
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
module Sidekiq
|
25
|
+
module Lock
|
26
|
+
describe Middleware do
|
27
|
+
|
28
|
+
def thread_variable
|
29
|
+
Thread.current[Sidekiq::Lock::THREAD_KEY]
|
30
|
+
end
|
31
|
+
|
32
|
+
before do
|
33
|
+
Sidekiq.redis = REDIS
|
34
|
+
Sidekiq.redis { |c| c.flushdb }
|
35
|
+
Thread.current[Sidekiq::Lock::THREAD_KEY] = nil
|
36
|
+
end
|
37
|
+
|
38
|
+
let(:handler){ Sidekiq::Lock::Middleware.new }
|
39
|
+
|
40
|
+
it 'sets lock variable with provided static lock options' do
|
41
|
+
handler.call(LockWorker.new, {'class' => LockWorker, 'args' => []}, 'default') do
|
42
|
+
true
|
43
|
+
end
|
44
|
+
|
45
|
+
assert_kind_of RedisLock, thread_variable
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'sets lock variable with provided dynamic options' do
|
49
|
+
handler.call(DynamicLockWorker.new, {'class' => DynamicLockWorker, 'args' => [1234, 1000]}, 'default') do
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
assert_equal "lock:1234", thread_variable.name
|
54
|
+
assert_equal 2000, thread_variable.timeout
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'sets nothing for workers without lock options' do
|
58
|
+
handler.call(RegularWorker.new, {'class' => RegularWorker, 'args' => []}, 'default') do
|
59
|
+
true
|
60
|
+
end
|
61
|
+
|
62
|
+
assert_nil thread_variable
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Lock
|
5
|
+
describe RedisLock do
|
6
|
+
before do
|
7
|
+
Sidekiq.redis = REDIS
|
8
|
+
Sidekiq.redis { |c| c.flushdb }
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:args) { [{'timeout' => 100, 'name' => 'test-lock'}, []] }
|
12
|
+
|
13
|
+
it "raises an error on missing timeout&name values" do
|
14
|
+
assert_raises ArgumentError do
|
15
|
+
RedisLock.new({},[])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "raises an error on missing timeout value" do
|
20
|
+
assert_raises ArgumentError do
|
21
|
+
RedisLock.new({ 'name' => 'this-is-lock' }, [])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "raises an error on missing name value" do
|
26
|
+
assert_raises ArgumentError do
|
27
|
+
RedisLock.new({ 'timeout' => 500 }, [])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it "does not raise an error when timeout and name is provided" do
|
32
|
+
assert RedisLock.new({ 'timeout' => 500, 'name' => 'lock-name' }, [])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "can accept block as arguments" do
|
36
|
+
lock = RedisLock.new({
|
37
|
+
'timeout' => proc { |options| options['timeout'] * 2 },
|
38
|
+
'name' => proc { |options| "#{options['test']}-sidekiq" }
|
39
|
+
}, ['timeout' => 500, 'test' => 'hello'])
|
40
|
+
|
41
|
+
assert_equal 1000, lock.timeout
|
42
|
+
assert_equal 'hello-sidekiq', lock.name
|
43
|
+
end
|
44
|
+
|
45
|
+
it "can acquire a lock" do
|
46
|
+
lock = RedisLock.new(*args)
|
47
|
+
assert lock.acquire!
|
48
|
+
end
|
49
|
+
|
50
|
+
it "cannot aquire lock if it's already taken by other process/thread" do
|
51
|
+
faster_lock = RedisLock.new(*args)
|
52
|
+
assert faster_lock.acquire!
|
53
|
+
|
54
|
+
slower_lock = RedisLock.new(*args)
|
55
|
+
refute slower_lock.acquire!
|
56
|
+
end
|
57
|
+
|
58
|
+
it "releases taken lock" do
|
59
|
+
lock = RedisLock.new(*args)
|
60
|
+
lock.acquire!
|
61
|
+
assert redis("get", "test-lock")
|
62
|
+
|
63
|
+
lock.release!
|
64
|
+
assert_nil redis("get", "test-lock")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "releases lock taken by another process without deleting lock key" do
|
68
|
+
lock = RedisLock.new(*args)
|
69
|
+
lock.acquire!
|
70
|
+
lock_value = redis("get", "test-lock")
|
71
|
+
assert lock_value
|
72
|
+
sleep 0.11 # timeout lock
|
73
|
+
|
74
|
+
new_lock = RedisLock.new(*args)
|
75
|
+
new_lock.acquire!
|
76
|
+
new_lock_value = redis("get", "test-lock")
|
77
|
+
|
78
|
+
lock.release!
|
79
|
+
|
80
|
+
assert_equal new_lock_value, redis("get", "test-lock")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "test_helper"
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
module Lock
|
5
|
+
describe Worker do
|
6
|
+
|
7
|
+
it 'sets lock method that points to thread variable' do
|
8
|
+
Thread.current[Sidekiq::Lock::THREAD_KEY] = "test"
|
9
|
+
assert_equal "test", LockWorker.new.lock
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Encoding.default_external = Encoding::UTF_8
|
2
|
+
Encoding.default_internal = Encoding::UTF_8
|
3
|
+
|
4
|
+
require "minitest/autorun"
|
5
|
+
require "minitest/pride"
|
6
|
+
|
7
|
+
require "sidekiq"
|
8
|
+
require "sidekiq-lock"
|
9
|
+
|
10
|
+
Sidekiq.logger.level = Logger::ERROR
|
11
|
+
|
12
|
+
REDIS = Sidekiq::RedisConnection.create(url: "redis://localhost/15", namespace: "sidekiq_lock_test")
|
13
|
+
|
14
|
+
def redis(command, *args)
|
15
|
+
Sidekiq.redis do |c|
|
16
|
+
c.send(command, *args)
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sidekiq-lock
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Rafal Wojsznis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-10-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sidekiq
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.14.0
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 2.14.0
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: redis
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 3.0.5
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 3.0.5
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.3'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.3'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rake
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rack-test
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
description: Simple redis-based lock mechanism for your sidekiq workers
|
95
|
+
email:
|
96
|
+
- rafal.wojsznis@gmail.com
|
97
|
+
executables: []
|
98
|
+
extensions: []
|
99
|
+
extra_rdoc_files: []
|
100
|
+
files:
|
101
|
+
- .gitignore
|
102
|
+
- .travis.yml
|
103
|
+
- CHANGELOG.md
|
104
|
+
- Gemfile
|
105
|
+
- LICENSE.txt
|
106
|
+
- README.md
|
107
|
+
- Rakefile
|
108
|
+
- lib/sidekiq-lock.rb
|
109
|
+
- lib/sidekiq/lock.rb
|
110
|
+
- lib/sidekiq/lock/middleware.rb
|
111
|
+
- lib/sidekiq/lock/redis_lock.rb
|
112
|
+
- lib/sidekiq/lock/version.rb
|
113
|
+
- lib/sidekiq/lock/worker.rb
|
114
|
+
- sidekiq-lock.gemspec
|
115
|
+
- test/lib/middleware_test.rb
|
116
|
+
- test/lib/redis_lock_test.rb
|
117
|
+
- test/lib/worker_test.rb
|
118
|
+
- test/test_helper.rb
|
119
|
+
homepage: https://github.com/emq/sidekiq-lock
|
120
|
+
licenses:
|
121
|
+
- MIT
|
122
|
+
post_install_message:
|
123
|
+
rdoc_options: []
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ! '>='
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
segments:
|
133
|
+
- 0
|
134
|
+
hash: 153540864602808106
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ! '>='
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
segments:
|
142
|
+
- 0
|
143
|
+
hash: 153540864602808106
|
144
|
+
requirements: []
|
145
|
+
rubyforge_project:
|
146
|
+
rubygems_version: 1.8.25
|
147
|
+
signing_key:
|
148
|
+
specification_version: 3
|
149
|
+
summary: Simple redis-based lock mechanism for your sidekiq workers
|
150
|
+
test_files:
|
151
|
+
- test/lib/middleware_test.rb
|
152
|
+
- test/lib/redis_lock_test.rb
|
153
|
+
- test/lib/worker_test.rb
|
154
|
+
- test/test_helper.rb
|