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 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
@@ -8,5 +8,5 @@ services:
8
8
  - redis-server
9
9
  matrix:
10
10
  allow_failures:
11
- - rvm: 2.0.0
11
+ - rvm: jruby-19mode
12
12
  - rvm: rbx-19mode
data/Gemfile CHANGED
@@ -1,2 +1,2 @@
1
- source :rubygems
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
- [![Build
7
- Status](https://secure.travis-ci.org/brainopia/sidekiq-limit_fetch.png)](http://travis-ci.org/brainopia/sidekiq-limit_fetch)
8
- [![Gem
9
- Version](https://badge.fury.io/rb/sidekiq-limit_fetch.png)](http://badge.fury.io/rb/sidekiq-limit_fetch)
10
- [![Dependency
11
- Status](https://gemnasium.com/brainopia/sidekiq-limit_fetch.png)](https://gemnasium.com/brainopia/sidekiq-limit_fetch)
12
- [![Code
13
- Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/brainopia/sidekiq-limit_fetch)
6
+ [![Build Status](https://secure.travis-ci.org/brainopia/sidekiq-limit_fetch.png)](http://travis-ci.org/brainopia/sidekiq-limit_fetch)
7
+ [![Gem Version](https://badge.fury.io/rb/sidekiq-limit_fetch.png)](http://badge.fury.io/rb/sidekiq-limit_fetch)
8
+ [![Dependency Status](https://gemnasium.com/brainopia/sidekiq-limit_fetch.png)](https://gemnasium.com/brainopia/sidekiq-limit_fetch)
9
+ [![Code Climate](https://codeclimate.com/github/brainopia/sidekiq-limit_fetch.png)](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, :limit=,
7
- :acquire, :release,
8
- :pause, :unpause,
9
- :block, :unblock,
10
- :paused?, :blocking?,
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 ||= SecureRandom.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 blocked
59
+ local blocking_mode
53
60
 
54
61
  for _, queue in ipairs(queues) do
55
- if not blocked then
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
- blocked = can_block and queue_locks > 0
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 = false
6
+ blocked = false
7
+ unblocked = []
8
+
7
9
  queues(names).select {|queue|
8
- next false if blocked
9
- blocked = true if not queue.paused? and queue.blocking? and queue.busy > 0
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 |name|
40
- Sidekiq::Queue[name].block
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
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'sidekiq-limit_fetch'
3
- gem.version = '1.1'
3
+ gem.version = '1.2'
4
4
  gem.authors = 'brainopia'
5
5
  gem.email = 'brainopia@evilmartians.com'
6
6
  gem.summary = 'Sidekiq strategy to support queue limits'
@@ -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.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-01-28 00:00:00.000000000 Z
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: ! " Sidekiq strategy to restrict number of workers\n which are
69
- able to run specified queues simultaneously.\n"
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: 1.8.24
111
+ rubygems_version: 2.0.0
125
112
  signing_key:
126
- specification_version: 3
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