sidekiq-limit_fetch 1.1 → 1.2
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 +7 -0
- data/.travis.yml +1 -1
- data/Gemfile +1 -1
- data/README.md +34 -15
- data/lib/sidekiq/extensions/queue.rb +6 -5
- data/lib/sidekiq/limit_fetch/global/selector.rb +17 -4
- data/lib/sidekiq/limit_fetch/global/semaphore.rb +5 -0
- data/lib/sidekiq/limit_fetch/local/selector.rb +10 -3
- data/lib/sidekiq/limit_fetch/local/semaphore.rb +7 -1
- data/lib/sidekiq/limit_fetch/queues.rb +6 -2
- data/sidekiq-limit_fetch.gemspec +1 -1
- data/spec/sidekiq/limit_fetch/queues_spec.rb +12 -0
- data/spec/sidekiq/limit_fetch_spec.rb +1 -1
- metadata +16 -29
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 49c36141cff8fd8e6ad664f6a2fbe07af64f21ce
|
|
4
|
+
data.tar.gz: bcd3045d1127d419892b6d917363cfaf6462c9f3
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 014d8dd3ff1dfedbf226c0e5fc58fdb57a34e0329b0ad56f3d607276d39c45317697fde7c13cfeb33efa86c16a14db8df7a30eb3103f70691dd93c183ba15201
|
|
7
|
+
data.tar.gz: a6c5d5c6c19a03fb727384dee9ac0119ae018ae0ce517922442b4f45dcc576cb7f9566385af3b1d6a5696f57837b0b3475796c0338f1cd38883bbf85bd5ed18b
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
source
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
2
|
gemspec
|
data/README.md
CHANGED
|
@@ -3,14 +3,10 @@
|
|
|
3
3
|
Sidekiq strategy to restrict number of workers
|
|
4
4
|
which are able to run specified queues simultaneously.
|
|
5
5
|
|
|
6
|
-
[](https://gemnasium.com/brainopia/sidekiq-limit_fetch)
|
|
12
|
-
[](https://codeclimate.com/github/brainopia/sidekiq-limit_fetch)
|
|
6
|
+
[](http://travis-ci.org/brainopia/sidekiq-limit_fetch)
|
|
7
|
+
[](http://badge.fury.io/rb/sidekiq-limit_fetch)
|
|
8
|
+
[](https://gemnasium.com/brainopia/sidekiq-limit_fetch)
|
|
9
|
+
[](https://codeclimate.com/github/brainopia/sidekiq-limit_fetch)
|
|
14
10
|
|
|
15
11
|
## Installation
|
|
16
12
|
|
|
@@ -43,6 +39,13 @@ workers simultaneously.
|
|
|
43
39
|
Ability to set limits dynamically allows you to resize worker
|
|
44
40
|
distribution among queues any time you want.
|
|
45
41
|
|
|
42
|
+
### Busy workers by queue
|
|
43
|
+
|
|
44
|
+
You can see how many workers currently handling a queue:
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
Sidekiq::Queue['name'].busy # number of busy workers
|
|
48
|
+
```
|
|
46
49
|
|
|
47
50
|
### Pauses
|
|
48
51
|
|
|
@@ -55,13 +58,6 @@ will be preserved.
|
|
|
55
58
|
Sidekiq::Queue['name'].unpause # allows workers to use the queue
|
|
56
59
|
```
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
You can see how many workers currently handling a queue:
|
|
60
|
-
|
|
61
|
-
```ruby
|
|
62
|
-
Sidekiq::Queue['name'].busy # number of busy workers
|
|
63
|
-
```
|
|
64
|
-
|
|
65
61
|
### Multiple processes
|
|
66
62
|
|
|
67
63
|
Limits are applied per process. In case you have several worker
|
|
@@ -106,6 +102,29 @@ You can also enable and disable blocking mode for queues on the fly:
|
|
|
106
102
|
Sidekiq::Queue['name'].unblock
|
|
107
103
|
```
|
|
108
104
|
|
|
105
|
+
### Advanced blocking queues
|
|
106
|
+
|
|
107
|
+
You can also block on array of queues. It means when any of them is
|
|
108
|
+
running only queues higher and queues from their blocking group can
|
|
109
|
+
run. It will be easier to understand with an example:
|
|
110
|
+
|
|
111
|
+
```yaml
|
|
112
|
+
:queues:
|
|
113
|
+
- a
|
|
114
|
+
- b
|
|
115
|
+
- c
|
|
116
|
+
- d
|
|
117
|
+
:blocking:
|
|
118
|
+
- [b, c]
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
In this case tasks from `d` will be blocked when a task from queue `b` or `c` is executed.
|
|
122
|
+
|
|
123
|
+
You can dynamically set exceptions for queue blocking:
|
|
124
|
+
|
|
125
|
+
```ruby
|
|
126
|
+
Sidekiq::Queue['queue1'].block_except 'queue2'
|
|
127
|
+
```
|
|
109
128
|
|
|
110
129
|
### Thanks
|
|
111
130
|
|
|
@@ -3,11 +3,12 @@ module Sidekiq
|
|
|
3
3
|
extend LimitFetch::Singleton, Forwardable
|
|
4
4
|
|
|
5
5
|
def_delegators :lock,
|
|
6
|
-
:limit,
|
|
7
|
-
:acquire,
|
|
8
|
-
:pause,
|
|
9
|
-
:block,
|
|
10
|
-
:paused?,
|
|
6
|
+
:limit, :limit=,
|
|
7
|
+
:acquire, :release,
|
|
8
|
+
:pause, :unpause,
|
|
9
|
+
:block, :unblock,
|
|
10
|
+
:paused?, :blocking?,
|
|
11
|
+
:unblocked, :block_except,
|
|
11
12
|
:busy
|
|
12
13
|
|
|
13
14
|
def lock
|
|
@@ -11,7 +11,13 @@ module Sidekiq::LimitFetch::Global
|
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def uuid
|
|
14
|
-
@uuid ||=
|
|
14
|
+
# - if we'll remove "@uuid ||=" from inside of mutex
|
|
15
|
+
# then @uuid can be overwritten
|
|
16
|
+
# - if we'll remove "@uuid ||=" from outside of mutex
|
|
17
|
+
# then each read will lead to mutex
|
|
18
|
+
@uuid ||= Thread.exclusive do
|
|
19
|
+
@uuid ||= SecureRandom.uuid
|
|
20
|
+
end
|
|
15
21
|
end
|
|
16
22
|
|
|
17
23
|
private
|
|
@@ -48,11 +54,12 @@ module Sidekiq::LimitFetch::Global
|
|
|
48
54
|
local worker_name = table.remove(ARGV, 1)
|
|
49
55
|
local queues = ARGV
|
|
50
56
|
local available = {}
|
|
57
|
+
local unblocked = {}
|
|
51
58
|
local queue_locks
|
|
52
|
-
local
|
|
59
|
+
local blocking_mode
|
|
53
60
|
|
|
54
61
|
for _, queue in ipairs(queues) do
|
|
55
|
-
if not
|
|
62
|
+
if not blocking_mode or unblocked[queue] then
|
|
56
63
|
local busy_key = namespace..'busy:'..queue
|
|
57
64
|
local pause_key = namespace..'pause:'..queue
|
|
58
65
|
local paused = redis.call('get', pause_key)
|
|
@@ -68,7 +75,13 @@ module Sidekiq::LimitFetch::Global
|
|
|
68
75
|
queue_locks = redis.call('llen', busy_key)
|
|
69
76
|
end
|
|
70
77
|
|
|
71
|
-
|
|
78
|
+
blocking_mode = can_block and queue_locks > 0
|
|
79
|
+
|
|
80
|
+
if blocking_mode and can_block ~= 'true' then
|
|
81
|
+
for unblocked_queue in string.gmatch(can_block, "[^,]+") do
|
|
82
|
+
unblocked[unblocked_queue] = true
|
|
83
|
+
end
|
|
84
|
+
end
|
|
72
85
|
|
|
73
86
|
if not queue_limit or queue_limit > queue_locks then
|
|
74
87
|
redis.call('rpush', busy_key, worker_name)
|
|
@@ -46,6 +46,11 @@ module Sidekiq::LimitFetch::Global
|
|
|
46
46
|
redis {|it| it.set "#{PREFIX}:block:#@name", true }
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
def block_except(*queues)
|
|
50
|
+
raise ArgumentError if queues.empty?
|
|
51
|
+
redis {|it| it.set "#{PREFIX}:block:#@name", queues.join(',') }
|
|
52
|
+
end
|
|
53
|
+
|
|
49
54
|
def unblock
|
|
50
55
|
redis {|it| it.del "#{PREFIX}:block:#@name" }
|
|
51
56
|
end
|
|
@@ -3,10 +3,17 @@ module Sidekiq::LimitFetch::Local
|
|
|
3
3
|
extend self
|
|
4
4
|
|
|
5
5
|
def acquire(names)
|
|
6
|
-
blocked
|
|
6
|
+
blocked = false
|
|
7
|
+
unblocked = []
|
|
8
|
+
|
|
7
9
|
queues(names).select {|queue|
|
|
8
|
-
next false
|
|
9
|
-
|
|
10
|
+
next false if blocked and not unblocked.include?(queue.name)
|
|
11
|
+
|
|
12
|
+
if not queue.paused? and queue.blocking? and queue.busy > 0
|
|
13
|
+
blocked = true
|
|
14
|
+
unblocked = queue.unblocked || []
|
|
15
|
+
end
|
|
16
|
+
|
|
10
17
|
queue.acquire
|
|
11
18
|
}.map(&:name)
|
|
12
19
|
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
module Sidekiq::LimitFetch::Local
|
|
2
2
|
class Semaphore
|
|
3
|
-
attr_reader :limit, :busy
|
|
3
|
+
attr_reader :limit, :busy, :unblocked
|
|
4
4
|
|
|
5
5
|
def initialize(name)
|
|
6
6
|
@name = name
|
|
@@ -44,6 +44,12 @@ module Sidekiq::LimitFetch::Local
|
|
|
44
44
|
@block = true
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
+
def block_except(*queues)
|
|
48
|
+
raise ArgumentError if queues.empty?
|
|
49
|
+
@unblocked = queues
|
|
50
|
+
@block = true
|
|
51
|
+
end
|
|
52
|
+
|
|
47
53
|
def unblock
|
|
48
54
|
@block = false
|
|
49
55
|
end
|
|
@@ -36,8 +36,12 @@ class Sidekiq::LimitFetch
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def set_blocks(blocks)
|
|
39
|
-
blocks.to_a.each do |
|
|
40
|
-
|
|
39
|
+
blocks.to_a.each do |it|
|
|
40
|
+
if it.is_a? Array
|
|
41
|
+
it.each {|name| Sidekiq::Queue[name].block_except it }
|
|
42
|
+
else
|
|
43
|
+
Sidekiq::Queue[it].block
|
|
44
|
+
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
43
47
|
|
data/sidekiq-limit_fetch.gemspec
CHANGED
|
@@ -40,6 +40,18 @@ describe Sidekiq::LimitFetch::Queues do
|
|
|
40
40
|
Sidekiq::Queue['queue2'].busy.should == 1
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
+
it 'should block except given queues' do
|
|
44
|
+
Sidekiq::Queue['queue1'].block_except 'queue2'
|
|
45
|
+
subject.acquire
|
|
46
|
+
Sidekiq::Queue['queue1'].busy.should == 1
|
|
47
|
+
Sidekiq::Queue['queue2'].busy.should == 1
|
|
48
|
+
|
|
49
|
+
Sidekiq::Queue['queue1'].block_except 'queue404'
|
|
50
|
+
subject.acquire
|
|
51
|
+
Sidekiq::Queue['queue1'].busy.should == 2
|
|
52
|
+
Sidekiq::Queue['queue2'].busy.should == 1
|
|
53
|
+
end
|
|
54
|
+
|
|
43
55
|
it 'should release queues' do
|
|
44
56
|
subject.acquire
|
|
45
57
|
subject.release_except nil
|
|
@@ -14,7 +14,7 @@ describe Sidekiq::LimitFetch do
|
|
|
14
14
|
let(:options) {{ queues: queues, limits: limits, global: global }}
|
|
15
15
|
let(:queues) { %w(queue1 queue1 queue2 queue2) }
|
|
16
16
|
let(:limits) {{ 'queue1' => 1, 'queue2' => 2 }}
|
|
17
|
-
|
|
17
|
+
|
|
18
18
|
shared_examples_for :strategy do
|
|
19
19
|
it 'should acquire lock on queue for execution' do
|
|
20
20
|
work = subject.retrieve_work
|
metadata
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sidekiq-limit_fetch
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: '1.
|
|
5
|
-
prerelease:
|
|
4
|
+
version: '1.2'
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- brainopia
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date: 2013-
|
|
11
|
+
date: 2013-03-10 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: sidekiq
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
|
-
- -
|
|
17
|
+
- - '>='
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
21
19
|
version: 2.6.5
|
|
22
20
|
- - <
|
|
@@ -25,9 +23,8 @@ dependencies:
|
|
|
25
23
|
type: :runtime
|
|
26
24
|
prerelease: false
|
|
27
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
28
|
-
none: false
|
|
29
26
|
requirements:
|
|
30
|
-
- -
|
|
27
|
+
- - '>='
|
|
31
28
|
- !ruby/object:Gem::Version
|
|
32
29
|
version: 2.6.5
|
|
33
30
|
- - <
|
|
@@ -36,37 +33,34 @@ dependencies:
|
|
|
36
33
|
- !ruby/object:Gem::Dependency
|
|
37
34
|
name: rspec
|
|
38
35
|
requirement: !ruby/object:Gem::Requirement
|
|
39
|
-
none: false
|
|
40
36
|
requirements:
|
|
41
|
-
- -
|
|
37
|
+
- - '>='
|
|
42
38
|
- !ruby/object:Gem::Version
|
|
43
39
|
version: '0'
|
|
44
40
|
type: :development
|
|
45
41
|
prerelease: false
|
|
46
42
|
version_requirements: !ruby/object:Gem::Requirement
|
|
47
|
-
none: false
|
|
48
43
|
requirements:
|
|
49
|
-
- -
|
|
44
|
+
- - '>='
|
|
50
45
|
- !ruby/object:Gem::Version
|
|
51
46
|
version: '0'
|
|
52
47
|
- !ruby/object:Gem::Dependency
|
|
53
48
|
name: rake
|
|
54
49
|
requirement: !ruby/object:Gem::Requirement
|
|
55
|
-
none: false
|
|
56
50
|
requirements:
|
|
57
|
-
- -
|
|
51
|
+
- - '>='
|
|
58
52
|
- !ruby/object:Gem::Version
|
|
59
53
|
version: '0'
|
|
60
54
|
type: :development
|
|
61
55
|
prerelease: false
|
|
62
56
|
version_requirements: !ruby/object:Gem::Requirement
|
|
63
|
-
none: false
|
|
64
57
|
requirements:
|
|
65
|
-
- -
|
|
58
|
+
- - '>='
|
|
66
59
|
- !ruby/object:Gem::Version
|
|
67
60
|
version: '0'
|
|
68
|
-
description:
|
|
69
|
-
|
|
61
|
+
description: |2
|
|
62
|
+
Sidekiq strategy to restrict number of workers
|
|
63
|
+
which are able to run specified queues simultaneously.
|
|
70
64
|
email: brainopia@evilmartians.com
|
|
71
65
|
executables: []
|
|
72
66
|
extensions: []
|
|
@@ -97,33 +91,26 @@ files:
|
|
|
97
91
|
- spec/spec_helper.rb
|
|
98
92
|
homepage: https://github.com/brainopia/sidekiq-limit_fetch
|
|
99
93
|
licenses: []
|
|
94
|
+
metadata: {}
|
|
100
95
|
post_install_message:
|
|
101
96
|
rdoc_options: []
|
|
102
97
|
require_paths:
|
|
103
98
|
- lib
|
|
104
99
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
|
-
none: false
|
|
106
100
|
requirements:
|
|
107
|
-
- -
|
|
101
|
+
- - '>='
|
|
108
102
|
- !ruby/object:Gem::Version
|
|
109
103
|
version: '0'
|
|
110
|
-
segments:
|
|
111
|
-
- 0
|
|
112
|
-
hash: -3014276428821981336
|
|
113
104
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
|
-
none: false
|
|
115
105
|
requirements:
|
|
116
|
-
- -
|
|
106
|
+
- - '>='
|
|
117
107
|
- !ruby/object:Gem::Version
|
|
118
108
|
version: '0'
|
|
119
|
-
segments:
|
|
120
|
-
- 0
|
|
121
|
-
hash: -3014276428821981336
|
|
122
109
|
requirements: []
|
|
123
110
|
rubyforge_project:
|
|
124
|
-
rubygems_version:
|
|
111
|
+
rubygems_version: 2.0.0
|
|
125
112
|
signing_key:
|
|
126
|
-
specification_version:
|
|
113
|
+
specification_version: 4
|
|
127
114
|
summary: Sidekiq strategy to support queue limits
|
|
128
115
|
test_files:
|
|
129
116
|
- spec/sidekiq/extensions/queue_spec.rb
|