sidekiq-limit_fetch 2.1.1 → 2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 37b25405100cca644241eb4c1106e31020ceaa71
4
- data.tar.gz: c6e906b7f2d5553807fcf36082116f5fe7c06824
3
+ metadata.gz: e0a7907ad1ad1e09f8c873c8131ae4f3fa7625b6
4
+ data.tar.gz: 24fa5bd726c2a6ca724cc55775b361bb98a5b818
5
5
  SHA512:
6
- metadata.gz: 0a3eeb2ee0098c67ae2971f4b62c4ab56526ddc1cd943d5cf39869d149baab4014382a6c696959a540d565584801e827facad77aad5286dbc8853aba872808ce
7
- data.tar.gz: e7f166cb5cbadf788662befcca218b4a501343e6d05f2c9ff76199a293b301ee92137a822cbc66fb008e63c754e2d0ebdfc8457b80c497463748594244582d8d
6
+ metadata.gz: 7c7f3d96c4e0eafb5c22db40913f6e52b8ca674688d3f7d2a11c20318a06c4752c485c7268e7d643b18817a024e61b2bf3da2ccb8d84833c9a09b3042b06b937
7
+ data.tar.gz: 822d2ec33178bbcbbb620c8b699f2429a74c53ed5e66bb3eaa90811badb827f7862176361b59ecab1b584b63baede9e4f290080d9bc36f6227fe3dc29952c621
data/demo/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails'
4
+ gem 'sinatra'
5
+ gem 'celluloid'
6
+ gem 'launchy'
7
+ gem 'sidekiq-limit_fetch'
8
+
data/demo/README.md ADDED
@@ -0,0 +1,2 @@
1
+ To test effect of limits run: `rake demo:limits`
2
+ To change simulation see `lib/tasks/demo.rake`
data/demo/Rakefile ADDED
@@ -0,0 +1,61 @@
1
+ require File.expand_path('../config/application', __FILE__)
2
+ Demo::Application.load_tasks
3
+
4
+ namespace :demo do
5
+ task limit: :environment do
6
+ puts '=> Creating sidekiq tasks'
7
+
8
+ 100.times do
9
+ SlowWorker.perform_async
10
+ FastWorker.perform_async
11
+ end
12
+
13
+ run_sidekiq_monitoring
14
+ run_sidekiq_workers config: <<-YAML
15
+ :verbose: false
16
+ :concurrency: 4
17
+ :queues:
18
+ - slow
19
+ - fast
20
+ :limits:
21
+ slow: 1
22
+ YAML
23
+ end
24
+
25
+ def with_sidekiq_config(config)
26
+ whitespace_offset = config[/\A */].size
27
+ config.gsub! /^ {#{whitespace_offset}}/, ''
28
+
29
+ puts "=> Use sidekiq config:\n#{config}"
30
+ File.write 'config/sidekiq.yml', config
31
+ yield
32
+ ensure
33
+ FileUtils.rm 'config/sidekiq.yml'
34
+ end
35
+
36
+ def run_sidekiq_monitoring
37
+ require 'sidekiq/web'
38
+ Thread.new do
39
+ Rack::Server.start app: Sidekiq::Web, Port: 3000
40
+ end
41
+ sleep 1
42
+ Launchy.open 'http://127.0.0.1:3000/workers?poll=true'
43
+ end
44
+
45
+ def run_sidekiq_workers(options)
46
+ require 'sidekiq/cli'
47
+ cli = Sidekiq::CLI.instance
48
+
49
+ %w(validate! boot_system).each do |stub|
50
+ cli.define_singleton_method(stub) {}
51
+ end
52
+
53
+ with_sidekiq_config options[:config] do
54
+ config = cli.send :parse_config, 'config/sidekiq.yml'
55
+ Sidekiq.options.merge! config
56
+ end
57
+
58
+ cli.run
59
+ end
60
+ end
61
+
@@ -0,0 +1,8 @@
1
+ class FastWorker
2
+ include Sidekiq::Worker
3
+ sidekiq_options queue: :fast
4
+
5
+ def perform
6
+ sleep 0.2
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ class SlowWorker
2
+ include Sidekiq::Worker
3
+ sidekiq_options queue: :slow
4
+
5
+ def perform
6
+ sleep 1
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require 'action_controller/railtie'
4
+ require 'action_mailer/railtie'
5
+ require 'sprockets/railtie'
6
+
7
+ Bundler.require(:default, Rails.env)
8
+
9
+ module Demo
10
+ Application = Class.new Rails::Application
11
+ end
@@ -0,0 +1,2 @@
1
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
2
+ require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
@@ -0,0 +1,2 @@
1
+ require File.expand_path('../application', __FILE__)
2
+ Demo::Application.initialize!
@@ -0,0 +1,9 @@
1
+ Demo::Application.configure do
2
+ config.cache_classes = false
3
+ config.eager_load = false
4
+ config.consider_all_requests_local = true
5
+ config.action_controller.perform_caching = false
6
+ config.action_mailer.raise_delivery_errors = false
7
+ config.active_support.deprecation = :log
8
+ config.assets.debug = true
9
+ end
@@ -2,17 +2,16 @@ module Sidekiq::LimitFetch::Global
2
2
  module Monitor
3
3
  extend self
4
4
 
5
- HEARTBEAT_NAMESPACE = 'heartbeat:'
6
- PROCESSOR_NAMESPACE = 'processor:'
7
-
8
- HEARTBEAT_TTL = 18
5
+ HEARTBEAT_PREFIX = 'heartbeat:'
6
+ PROCESS_SET = 'processes'
7
+ HEARTBEAT_TTL = 18
9
8
  REFRESH_TIMEOUT = 10
10
9
 
11
10
  def start!(ttl=HEARTBEAT_TTL, timeout=REFRESH_TIMEOUT)
12
11
  Thread.new do
13
12
  loop do
14
13
  update_heartbeat ttl
15
- invalidate_old_processors
14
+ invalidate_old_processes
16
15
  sleep timeout
17
16
  end
18
17
  end
@@ -23,35 +22,36 @@ module Sidekiq::LimitFetch::Global
23
22
  def update_heartbeat(ttl)
24
23
  Sidekiq.redis do |it|
25
24
  it.pipelined do
26
- it.set processor_key, true
25
+ it.sadd PROCESS_SET, Selector.uuid
27
26
  it.set heartbeat_key, true
28
27
  it.expire heartbeat_key, ttl
29
28
  end
30
29
  end
31
30
  end
32
31
 
33
- def invalidate_old_processors
32
+ def invalidate_old_processes
34
33
  Sidekiq.redis do |it|
35
- it.keys(PROCESSOR_NAMESPACE + '*').each do |processor|
36
- processor.sub! PROCESSOR_NAMESPACE, ''
37
- next if it.get heartbeat_key processor
34
+ processes = it.smembers PROCESS_SET
35
+ processes.each do |process|
36
+ unless it.get heartbeat_key process
37
+ processes.delete process
38
+ it.srem PROCESS_SET, process
39
+ end
40
+ end
38
41
 
39
- it.del processor_key processor
40
- %w(limit_fetch:probed:* limit_fetch:busy:*).each do |pattern|
41
- it.keys(pattern).each do |queue|
42
- it.lrem queue, 0, processor
42
+ Sidekiq::Queue.instances.map(&:name).uniq.each do |queue|
43
+ locks = it.lrange "limit_fetch:probed:#{queue}", 0, -1
44
+ (locks.uniq - processes).each do |dead_process|
45
+ %w(limit_fetch:probed: limit_fetch:busy:).each do |prefix|
46
+ it.lrem prefix + queue, 0, dead_process
43
47
  end
44
48
  end
45
49
  end
46
50
  end
47
51
  end
48
52
 
49
- def heartbeat_key(processor=Selector.uuid)
50
- HEARTBEAT_NAMESPACE + processor
51
- end
52
-
53
- def processor_key(processor=Selector.uuid)
54
- PROCESSOR_NAMESPACE + processor
53
+ def heartbeat_key(process=Selector.uuid)
54
+ HEARTBEAT_PREFIX + process
55
55
  end
56
56
  end
57
57
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'sidekiq-limit_fetch'
3
- gem.version = '2.1.1'
3
+ gem.version = '2.1.2'
4
4
  gem.authors = 'brainopia'
5
5
  gem.email = 'brainopia@evilmartians.com'
6
6
  gem.summary = 'Sidekiq strategy to support queue limits'
@@ -1,5 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
+ Thread.abort_on_exception = true
4
+
3
5
  describe Sidekiq::LimitFetch::Global::Monitor do
4
6
  let(:monitor) { described_class.start! ttl, timeout }
5
7
  let(:ttl) { 1 }
@@ -26,5 +28,15 @@ describe Sidekiq::LimitFetch::Global::Monitor do
26
28
  sleep 2*ttl
27
29
  queue.probed.should == 0
28
30
  end
31
+
32
+ it 'should remove invalid locks' do
33
+ 2.times { queue.acquire }
34
+ described_class.stub :update_heartbeat
35
+ Sidekiq.redis do |it|
36
+ it.del Sidekiq::LimitFetch::Global::Monitor::PROCESS_SET
37
+ end
38
+ sleep 2*ttl
39
+ queue.probed.should == 0
40
+ end
29
41
  end
30
42
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sidekiq-limit_fetch
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 2.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - brainopia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-06-22 00:00:00.000000000 Z
11
+ date: 2013-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sidekiq
@@ -73,6 +73,15 @@ files:
73
73
  - README.md
74
74
  - Rakefile
75
75
  - bench/compare.rb
76
+ - demo/Gemfile
77
+ - demo/README.md
78
+ - demo/Rakefile
79
+ - demo/app/workers/fast_worker.rb
80
+ - demo/app/workers/slow_worker.rb
81
+ - demo/config/application.rb
82
+ - demo/config/boot.rb
83
+ - demo/config/environment.rb
84
+ - demo/config/environments/development.rb
76
85
  - lib/sidekiq-limit_fetch.rb
77
86
  - lib/sidekiq/extensions/queue.rb
78
87
  - lib/sidekiq/limit_fetch.rb
@@ -109,7 +118,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
118
  version: '0'
110
119
  requirements: []
111
120
  rubyforge_project:
112
- rubygems_version: 2.0.2
121
+ rubygems_version: 2.0.3
113
122
  signing_key:
114
123
  specification_version: 4
115
124
  summary: Sidekiq strategy to support queue limits
@@ -120,3 +129,4 @@ test_files:
120
129
  - spec/sidekiq/limit_fetch/semaphore_spec.rb
121
130
  - spec/sidekiq/limit_fetch_spec.rb
122
131
  - spec/spec_helper.rb
132
+ has_rdoc: