sidekiq 2.15.1 → 4.2.10
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sidekiq might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/.github/contributing.md +32 -0
- data/.github/issue_template.md +9 -0
- data/.gitignore +1 -0
- data/.travis.yml +16 -17
- data/3.0-Upgrade.md +70 -0
- data/4.0-Upgrade.md +53 -0
- data/COMM-LICENSE +56 -44
- data/Changes.md +644 -1
- data/Ent-Changes.md +173 -0
- data/Gemfile +27 -0
- data/LICENSE +1 -1
- data/Pro-2.0-Upgrade.md +138 -0
- data/Pro-3.0-Upgrade.md +44 -0
- data/Pro-Changes.md +457 -3
- data/README.md +46 -29
- data/Rakefile +6 -3
- data/bin/sidekiq +4 -0
- data/bin/sidekiqctl +41 -20
- data/bin/sidekiqload +154 -0
- data/code_of_conduct.md +50 -0
- data/lib/generators/sidekiq/templates/worker.rb.erb +9 -0
- data/lib/generators/sidekiq/templates/worker_spec.rb.erb +6 -0
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +8 -0
- data/lib/generators/sidekiq/worker_generator.rb +49 -0
- data/lib/sidekiq.rb +141 -29
- data/lib/sidekiq/api.rb +540 -106
- data/lib/sidekiq/cli.rb +131 -71
- data/lib/sidekiq/client.rb +168 -96
- data/lib/sidekiq/core_ext.rb +36 -8
- data/lib/sidekiq/exception_handler.rb +20 -28
- data/lib/sidekiq/extensions/action_mailer.rb +25 -5
- data/lib/sidekiq/extensions/active_record.rb +8 -4
- data/lib/sidekiq/extensions/class_methods.rb +9 -5
- data/lib/sidekiq/extensions/generic_proxy.rb +1 -0
- data/lib/sidekiq/fetch.rb +45 -101
- data/lib/sidekiq/launcher.rb +144 -30
- data/lib/sidekiq/logging.rb +69 -12
- data/lib/sidekiq/manager.rb +90 -140
- data/lib/sidekiq/middleware/chain.rb +18 -5
- data/lib/sidekiq/middleware/i18n.rb +9 -2
- data/lib/sidekiq/middleware/server/active_record.rb +1 -1
- data/lib/sidekiq/middleware/server/logging.rb +11 -11
- data/lib/sidekiq/middleware/server/retry_jobs.rb +98 -44
- data/lib/sidekiq/paginator.rb +20 -8
- data/lib/sidekiq/processor.rb +157 -96
- data/lib/sidekiq/rails.rb +109 -5
- data/lib/sidekiq/redis_connection.rb +70 -24
- data/lib/sidekiq/scheduled.rb +122 -50
- data/lib/sidekiq/testing.rb +171 -31
- data/lib/sidekiq/testing/inline.rb +1 -0
- data/lib/sidekiq/util.rb +31 -5
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web.rb +136 -263
- data/lib/sidekiq/web/action.rb +93 -0
- data/lib/sidekiq/web/application.rb +336 -0
- data/lib/sidekiq/web/helpers.rb +278 -0
- data/lib/sidekiq/web/router.rb +100 -0
- data/lib/sidekiq/worker.rb +40 -7
- data/sidekiq.gemspec +18 -14
- data/web/assets/images/favicon.ico +0 -0
- data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
- data/web/assets/javascripts/application.js +67 -19
- data/web/assets/javascripts/dashboard.js +138 -29
- data/web/assets/stylesheets/application.css +267 -406
- data/web/assets/stylesheets/bootstrap.css +4 -8
- data/web/locales/cs.yml +78 -0
- data/web/locales/da.yml +9 -1
- data/web/locales/de.yml +18 -9
- data/web/locales/el.yml +68 -0
- data/web/locales/en.yml +19 -4
- data/web/locales/es.yml +10 -1
- data/web/locales/fa.yml +79 -0
- data/web/locales/fr.yml +50 -32
- data/web/locales/hi.yml +75 -0
- data/web/locales/it.yml +27 -18
- data/web/locales/ja.yml +27 -12
- data/web/locales/ko.yml +8 -3
- data/web/locales/{no.yml → nb.yml} +19 -5
- data/web/locales/nl.yml +8 -3
- data/web/locales/pl.yml +0 -1
- data/web/locales/pt-br.yml +11 -4
- data/web/locales/pt.yml +8 -1
- data/web/locales/ru.yml +39 -21
- data/web/locales/sv.yml +68 -0
- data/web/locales/ta.yml +75 -0
- data/web/locales/uk.yml +76 -0
- data/web/locales/zh-cn.yml +68 -0
- data/web/locales/zh-tw.yml +68 -0
- data/web/views/_footer.erb +17 -0
- data/web/views/_job_info.erb +72 -60
- data/web/views/_nav.erb +58 -25
- data/web/views/_paging.erb +5 -5
- data/web/views/_poll_link.erb +7 -0
- data/web/views/_summary.erb +20 -14
- data/web/views/busy.erb +94 -0
- data/web/views/dashboard.erb +34 -21
- data/web/views/dead.erb +34 -0
- data/web/views/layout.erb +8 -30
- data/web/views/morgue.erb +75 -0
- data/web/views/queue.erb +37 -30
- data/web/views/queues.erb +26 -20
- data/web/views/retries.erb +60 -47
- data/web/views/retry.erb +23 -19
- data/web/views/scheduled.erb +39 -35
- data/web/views/scheduled_job_info.erb +2 -1
- metadata +152 -195
- data/Contributing.md +0 -29
- data/config.ru +0 -18
- data/lib/sidekiq/actor.rb +0 -7
- data/lib/sidekiq/capistrano.rb +0 -54
- data/lib/sidekiq/yaml_patch.rb +0 -21
- data/test/config.yml +0 -11
- data/test/env_based_config.yml +0 -11
- data/test/fake_env.rb +0 -0
- data/test/helper.rb +0 -42
- data/test/test_api.rb +0 -341
- data/test/test_cli.rb +0 -326
- data/test/test_client.rb +0 -211
- data/test/test_exception_handler.rb +0 -124
- data/test/test_extensions.rb +0 -105
- data/test/test_fetch.rb +0 -44
- data/test/test_manager.rb +0 -83
- data/test/test_middleware.rb +0 -135
- data/test/test_processor.rb +0 -160
- data/test/test_redis_connection.rb +0 -97
- data/test/test_retry.rb +0 -306
- data/test/test_scheduled.rb +0 -86
- data/test/test_scheduling.rb +0 -47
- data/test/test_sidekiq.rb +0 -37
- data/test/test_testing.rb +0 -82
- data/test/test_testing_fake.rb +0 -265
- data/test/test_testing_inline.rb +0 -92
- data/test/test_util.rb +0 -18
- data/test/test_web.rb +0 -372
- data/web/assets/images/bootstrap/glyphicons-halflings-white.png +0 -0
- data/web/assets/images/bootstrap/glyphicons-halflings.png +0 -0
- data/web/assets/images/status/active.png +0 -0
- data/web/assets/images/status/idle.png +0 -0
- data/web/assets/javascripts/locales/README.md +0 -27
- data/web/assets/javascripts/locales/jquery.timeago.ar.js +0 -96
- data/web/assets/javascripts/locales/jquery.timeago.bg.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.bs.js +0 -49
- data/web/assets/javascripts/locales/jquery.timeago.ca.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.cz.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.da.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.de.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.el.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.en-short.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.en.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.es.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.et.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.fa.js +0 -22
- data/web/assets/javascripts/locales/jquery.timeago.fi.js +0 -28
- data/web/assets/javascripts/locales/jquery.timeago.fr-short.js +0 -16
- data/web/assets/javascripts/locales/jquery.timeago.fr.js +0 -17
- data/web/assets/javascripts/locales/jquery.timeago.he.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.hr.js +0 -49
- data/web/assets/javascripts/locales/jquery.timeago.hu.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.hy.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.id.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.it.js +0 -16
- data/web/assets/javascripts/locales/jquery.timeago.ja.js +0 -19
- data/web/assets/javascripts/locales/jquery.timeago.ko.js +0 -17
- data/web/assets/javascripts/locales/jquery.timeago.lt.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.mk.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.no.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.pl.js +0 -31
- data/web/assets/javascripts/locales/jquery.timeago.pt-br.js +0 -16
- data/web/assets/javascripts/locales/jquery.timeago.pt.js +0 -16
- data/web/assets/javascripts/locales/jquery.timeago.ro.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.rs.js +0 -49
- data/web/assets/javascripts/locales/jquery.timeago.ru.js +0 -34
- data/web/assets/javascripts/locales/jquery.timeago.sk.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.sl.js +0 -44
- data/web/assets/javascripts/locales/jquery.timeago.sv.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.th.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.tr.js +0 -16
- data/web/assets/javascripts/locales/jquery.timeago.uk.js +0 -34
- data/web/assets/javascripts/locales/jquery.timeago.uz.js +0 -19
- data/web/assets/javascripts/locales/jquery.timeago.zh-CN.js +0 -20
- data/web/assets/javascripts/locales/jquery.timeago.zh-TW.js +0 -20
- data/web/views/_poll.erb +0 -14
- data/web/views/_workers.erb +0 -29
- data/web/views/index.erb +0 -16
data/Contributing.md
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# Contributing
|
2
|
-
|
3
|
-
First of all, thank you for even opening this file up! I hope you find
|
4
|
-
it worthwhile to help out with Sidekiq.
|
5
|
-
|
6
|
-
## Issues
|
7
|
-
|
8
|
-
When opening an issue, please include a **backtrace** with your error.
|
9
|
-
|
10
|
-
## Code
|
11
|
-
|
12
|
-
If you're interested in helping or contributing to Sidekiq, here's
|
13
|
-
some known areas which need improvement:
|
14
|
-
|
15
|
-
* The Web UI and sidekiq.org website could always use more polish. If you have an eye for design and an idea for improvement, please open an issue and let us know.
|
16
|
-
* The Sidekiq API has a serious issue: deleting elements and iterating
|
17
|
-
at the same time is broken, see #866, #1060.
|
18
|
-
* Make normal testing and inline testing dynamic: #1053
|
19
|
-
* Your brilliant idea which I haven't listed!
|
20
|
-
|
21
|
-
It's always best to open an issue before investing a lot of time into a
|
22
|
-
fix or new functionality. Functionality must meet my design goals and
|
23
|
-
vision for the project to be accepted; I would be happy to discuss how
|
24
|
-
your idea can best fit into Sidekiq.
|
25
|
-
|
26
|
-
|
27
|
-
## Sponsorship
|
28
|
-
|
29
|
-
If you've got more money than time and want to sponsor Sidekiq's continued support, your company can buy [Sidekiq Pro](http://sidekiq.org/pro). You get great functionality, I continue to fix bugs and enhance Sidekiq for years to come.
|
data/config.ru
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'sidekiq'
|
2
|
-
|
3
|
-
Sidekiq.configure_client do |config|
|
4
|
-
config.redis = { :size => 1 }
|
5
|
-
end
|
6
|
-
|
7
|
-
#Sidekiq.redis {|conn| conn.flushdb }
|
8
|
-
#10.times do |idx|
|
9
|
-
#Sidekiq::Client.push('class' => 'HardWorker', 'args' => ['foo', 0.1, idx])
|
10
|
-
#end
|
11
|
-
|
12
|
-
#Sidekiq.redis { |conn| conn.zadd('retry', Time.now.utc.to_f + 3000, MultiJson.encode({
|
13
|
-
#'class' => 'HardWorker', 'args' => ['foo', 0.1, Time.now.to_f],
|
14
|
-
#'queue' => 'default', 'error_message' => 'No such method', 'error_class' => 'NoMethodError',
|
15
|
-
#'failed_at' => Time.now.utc, 'retry_count' => 0 })) }
|
16
|
-
|
17
|
-
require 'sidekiq/web'
|
18
|
-
run Sidekiq::Web
|
data/lib/sidekiq/actor.rb
DELETED
data/lib/sidekiq/capistrano.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
Capistrano::Configuration.instance.load do
|
2
|
-
|
3
|
-
_cset(:sidekiq_default_hooks) { true }
|
4
|
-
_cset(:sidekiq_cmd) { "#{fetch(:bundle_cmd, "bundle")} exec sidekiq" }
|
5
|
-
_cset(:sidekiqctl_cmd) { "#{fetch(:bundle_cmd, "bundle")} exec sidekiqctl" }
|
6
|
-
_cset(:sidekiq_timeout) { 10 }
|
7
|
-
_cset(:sidekiq_role) { :app }
|
8
|
-
_cset(:sidekiq_pid) { "#{current_path}/tmp/pids/sidekiq.pid" }
|
9
|
-
_cset(:sidekiq_processes) { 1 }
|
10
|
-
|
11
|
-
if fetch(:sidekiq_default_hooks)
|
12
|
-
before "deploy:update_code", "sidekiq:quiet"
|
13
|
-
after "deploy:stop", "sidekiq:stop"
|
14
|
-
after "deploy:start", "sidekiq:start"
|
15
|
-
before "deploy:restart", "sidekiq:restart"
|
16
|
-
end
|
17
|
-
|
18
|
-
namespace :sidekiq do
|
19
|
-
def for_each_process(&block)
|
20
|
-
fetch(:sidekiq_processes).times do |idx|
|
21
|
-
yield((idx == 0 ? "#{fetch(:sidekiq_pid)}" : "#{fetch(:sidekiq_pid)}-#{idx}"), idx)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
desc "Quiet sidekiq (stop accepting new work)"
|
26
|
-
task :quiet, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
|
27
|
-
for_each_process do |pid_file, idx|
|
28
|
-
run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} quiet #{pid_file} ; else echo 'Sidekiq is not running'; fi"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
desc "Stop sidekiq"
|
33
|
-
task :stop, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
|
34
|
-
for_each_process do |pid_file, idx|
|
35
|
-
run "if [ -d #{current_path} ] && [ -f #{pid_file} ] && kill -0 `cat #{pid_file}`> /dev/null 2>&1; then cd #{current_path} && #{fetch(:sidekiqctl_cmd)} stop #{pid_file} #{fetch :sidekiq_timeout} ; else echo 'Sidekiq is not running'; fi"
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
desc "Start sidekiq"
|
40
|
-
task :start, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
|
41
|
-
rails_env = fetch(:rails_env, "production")
|
42
|
-
for_each_process do |pid_file, idx|
|
43
|
-
run "cd #{current_path} ; nohup #{fetch(:sidekiq_cmd)} -e #{rails_env} -C #{current_path}/config/sidekiq.yml -i #{idx} -P #{pid_file} >> #{current_path}/log/sidekiq.log 2>&1 &", :pty => false
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
desc "Restart sidekiq"
|
48
|
-
task :restart, :roles => lambda { fetch(:sidekiq_role) }, :on_no_matching_servers => :continue do
|
49
|
-
stop
|
50
|
-
start
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
end
|
data/lib/sidekiq/yaml_patch.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
# YAML marshalling of instances can fail in some circumstances,
|
2
|
-
# e.g. when the instance has a handle to a Proc. This monkeypatch limits
|
3
|
-
# the YAML serialization to just AR's internal @attributes hash.
|
4
|
-
# The paperclip gem litters AR instances with Procs, for instance.
|
5
|
-
#
|
6
|
-
# Courtesy of @ryanlecompte https://gist.github.com/007b88ae90372d1a3321
|
7
|
-
#
|
8
|
-
|
9
|
-
if defined?(::ActiveRecord)
|
10
|
-
class ActiveRecord::Base
|
11
|
-
yaml_as "tag:ruby.yaml.org,2002:ActiveRecord"
|
12
|
-
|
13
|
-
def self.yaml_new(klass, tag, val)
|
14
|
-
klass.unscoped.find(val['attributes'][klass.primary_key])
|
15
|
-
end
|
16
|
-
|
17
|
-
def to_yaml_properties
|
18
|
-
['@attributes']
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
data/test/config.yml
DELETED
data/test/env_based_config.yml
DELETED
data/test/fake_env.rb
DELETED
File without changes
|
data/test/helper.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
$TESTING = true
|
2
|
-
require 'coveralls'
|
3
|
-
Coveralls.wear! do
|
4
|
-
add_filter "/test/"
|
5
|
-
end
|
6
|
-
|
7
|
-
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = 'test'
|
8
|
-
if ENV.has_key?("SIMPLECOV")
|
9
|
-
require 'simplecov'
|
10
|
-
SimpleCov.start do
|
11
|
-
add_filter "/test/"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
begin
|
16
|
-
require 'pry'
|
17
|
-
rescue LoadError
|
18
|
-
end
|
19
|
-
|
20
|
-
require 'minitest/autorun'
|
21
|
-
require 'minitest/pride'
|
22
|
-
|
23
|
-
require 'celluloid/autostart'
|
24
|
-
require 'sidekiq'
|
25
|
-
require 'sidekiq/util'
|
26
|
-
Sidekiq.logger.level = Logger::ERROR
|
27
|
-
|
28
|
-
Sidekiq::Test = MiniTest::Unit::TestCase
|
29
|
-
|
30
|
-
require 'sidekiq/redis_connection'
|
31
|
-
redis_url = ENV['REDIS_URL'] || 'redis://localhost/15'
|
32
|
-
REDIS = Sidekiq::RedisConnection.create(:url => redis_url, :namespace => 'testy')
|
33
|
-
|
34
|
-
Sidekiq.configure_client do |config|
|
35
|
-
config.redis = { :url => redis_url, :namespace => 'testy' }
|
36
|
-
end
|
37
|
-
|
38
|
-
Celluloid.class_eval do
|
39
|
-
def self.shutdown
|
40
|
-
$stderr.puts "Celluloid shutdown disabled"
|
41
|
-
end
|
42
|
-
end
|
data/test/test_api.rb
DELETED
@@ -1,341 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestApi < Sidekiq::Test
|
4
|
-
describe "stats" do
|
5
|
-
before do
|
6
|
-
Sidekiq.redis {|c| c.flushdb }
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "processed" do
|
10
|
-
it "is initially zero" do
|
11
|
-
s = Sidekiq::Stats.new
|
12
|
-
assert_equal 0, s.processed
|
13
|
-
end
|
14
|
-
|
15
|
-
it "returns number of processed jobs" do
|
16
|
-
Sidekiq.redis { |conn| conn.set("stat:processed", 5) }
|
17
|
-
s = Sidekiq::Stats.new
|
18
|
-
assert_equal 5, s.processed
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
describe "failed" do
|
23
|
-
it "is initially zero" do
|
24
|
-
s = Sidekiq::Stats.new
|
25
|
-
assert_equal 0, s.processed
|
26
|
-
end
|
27
|
-
|
28
|
-
it "returns number of failed jobs" do
|
29
|
-
Sidekiq.redis { |conn| conn.set("stat:failed", 5) }
|
30
|
-
s = Sidekiq::Stats.new
|
31
|
-
assert_equal 5, s.failed
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe "reset" do
|
36
|
-
it 'can reset stats' do
|
37
|
-
Sidekiq.redis do |conn|
|
38
|
-
conn.set('stat:processed', 5)
|
39
|
-
conn.set('stat:failed', 10)
|
40
|
-
Sidekiq::Stats.new.reset
|
41
|
-
assert_equal '0', conn.get('stat:processed')
|
42
|
-
assert_equal '0', conn.get('stat:failed')
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe "queues" do
|
48
|
-
it "is initially empty" do
|
49
|
-
s = Sidekiq::Stats.new
|
50
|
-
assert_equal 0, s.queues.size
|
51
|
-
end
|
52
|
-
|
53
|
-
it "returns a hash of queue and size in order" do
|
54
|
-
Sidekiq.redis do |conn|
|
55
|
-
conn.rpush 'queue:foo', '{}'
|
56
|
-
conn.sadd 'queues', 'foo'
|
57
|
-
|
58
|
-
3.times { conn.rpush 'queue:bar', '{}' }
|
59
|
-
conn.sadd 'queues', 'bar'
|
60
|
-
end
|
61
|
-
|
62
|
-
s = Sidekiq::Stats.new
|
63
|
-
assert_equal ({ "foo" => 1, "bar" => 3 }), s.queues
|
64
|
-
assert_equal "bar", s.queues.first.first
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
describe "enqueued" do
|
69
|
-
it "is initially empty" do
|
70
|
-
s = Sidekiq::Stats.new
|
71
|
-
assert_equal 0, s.enqueued
|
72
|
-
end
|
73
|
-
|
74
|
-
it "returns total enqueued jobs" do
|
75
|
-
Sidekiq.redis do |conn|
|
76
|
-
conn.rpush 'queue:foo', '{}'
|
77
|
-
conn.sadd 'queues', 'foo'
|
78
|
-
|
79
|
-
3.times { conn.rpush 'queue:bar', '{}' }
|
80
|
-
conn.sadd 'queues', 'bar'
|
81
|
-
end
|
82
|
-
|
83
|
-
s = Sidekiq::Stats.new
|
84
|
-
assert_equal 4, s.enqueued
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe "over time" do
|
89
|
-
describe "processed" do
|
90
|
-
it 'retrieves hash of dates' do
|
91
|
-
Sidekiq.redis do |c|
|
92
|
-
c.incrby("stat:processed:2012-12-24", 4)
|
93
|
-
c.incrby("stat:processed:2012-12-25", 1)
|
94
|
-
c.incrby("stat:processed:2012-12-26", 6)
|
95
|
-
c.incrby("stat:processed:2012-12-27", 2)
|
96
|
-
end
|
97
|
-
Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
|
98
|
-
s = Sidekiq::Stats::History.new(2)
|
99
|
-
assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1 }), s.processed
|
100
|
-
|
101
|
-
s = Sidekiq::Stats::History.new(3)
|
102
|
-
assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }), s.processed
|
103
|
-
|
104
|
-
s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
|
105
|
-
assert_equal ({ "2012-12-25" => 1, "2012-12-24" => 4 }), s.processed
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
describe "failed" do
|
111
|
-
it 'retrieves hash of dates' do
|
112
|
-
Sidekiq.redis do |c|
|
113
|
-
c.incrby("stat:failed:2012-12-24", 4)
|
114
|
-
c.incrby("stat:failed:2012-12-25", 1)
|
115
|
-
c.incrby("stat:failed:2012-12-26", 6)
|
116
|
-
c.incrby("stat:failed:2012-12-27", 2)
|
117
|
-
end
|
118
|
-
Time.stub(:now, Time.parse("2012-12-26 1:00:00 -0500")) do
|
119
|
-
s = Sidekiq::Stats::History.new(2)
|
120
|
-
assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1 }), s.failed
|
121
|
-
|
122
|
-
s = Sidekiq::Stats::History.new(3)
|
123
|
-
assert_equal ({ "2012-12-26" => 6, "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
|
124
|
-
|
125
|
-
s = Sidekiq::Stats::History.new(2, Date.parse("2012-12-25"))
|
126
|
-
assert_equal ({ "2012-12-25" => 1, "2012-12-24" => 4 }), s.failed
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
describe 'with an empty database' do
|
134
|
-
before do
|
135
|
-
Sidekiq.redis {|c| c.flushdb }
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'shows queue as empty' do
|
139
|
-
q = Sidekiq::Queue.new
|
140
|
-
assert_equal 0, q.size
|
141
|
-
assert_equal 0, q.latency
|
142
|
-
end
|
143
|
-
|
144
|
-
class ApiWorker
|
145
|
-
include Sidekiq::Worker
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'can enumerate jobs' do
|
149
|
-
q = Sidekiq::Queue.new
|
150
|
-
Time.stub(:now, Time.new(2012, 12, 26)) do
|
151
|
-
ApiWorker.perform_async(1, 'mike')
|
152
|
-
assert_equal ['TestApi::ApiWorker'], q.map(&:klass)
|
153
|
-
|
154
|
-
job = q.first
|
155
|
-
assert_equal 24, job.jid.size
|
156
|
-
assert_equal [1, 'mike'], job.args
|
157
|
-
assert_equal Time.new(2012, 12, 26), job.enqueued_at
|
158
|
-
|
159
|
-
end
|
160
|
-
|
161
|
-
assert q.latency > 10_000_000
|
162
|
-
|
163
|
-
q = Sidekiq::Queue.new('other')
|
164
|
-
assert_equal 0, q.size
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'can delete jobs' do
|
168
|
-
q = Sidekiq::Queue.new
|
169
|
-
ApiWorker.perform_async(1, 'mike')
|
170
|
-
assert_equal 1, q.size
|
171
|
-
assert_equal [true], q.map(&:delete)
|
172
|
-
assert_equal 0, q.size
|
173
|
-
end
|
174
|
-
|
175
|
-
it "can move scheduled job to queue" do
|
176
|
-
job_id = ApiWorker.perform_in(100, 1, 'jason')
|
177
|
-
job = Sidekiq::ScheduledSet.new.find_job(job_id)
|
178
|
-
q = Sidekiq::Queue.new
|
179
|
-
job.add_to_queue
|
180
|
-
queued_job = q.find_job(job_id)
|
181
|
-
refute_nil queued_job
|
182
|
-
assert_equal queued_job.jid, job_id
|
183
|
-
job = Sidekiq::ScheduledSet.new.find_job(job_id)
|
184
|
-
assert_nil job
|
185
|
-
end
|
186
|
-
|
187
|
-
it 'can find job by id in sorted sets' do
|
188
|
-
job_id = ApiWorker.perform_in(100, 1, 'jason')
|
189
|
-
job = Sidekiq::ScheduledSet.new.find_job(job_id)
|
190
|
-
refute_nil job
|
191
|
-
assert_equal job_id, job.jid
|
192
|
-
assert_in_delta job.latency, 0.0, 0.01
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'can find job by id in queues' do
|
196
|
-
q = Sidekiq::Queue.new
|
197
|
-
job_id = ApiWorker.perform_async(1, 'jason')
|
198
|
-
job = q.find_job(job_id)
|
199
|
-
refute_nil job
|
200
|
-
assert_equal job_id, job.jid
|
201
|
-
end
|
202
|
-
|
203
|
-
it 'can clear a queue' do
|
204
|
-
q = Sidekiq::Queue.new
|
205
|
-
2.times { ApiWorker.perform_async(1, 'mike') }
|
206
|
-
q.clear
|
207
|
-
|
208
|
-
Sidekiq.redis do |conn|
|
209
|
-
refute conn.smembers('queues').include?('foo')
|
210
|
-
refute conn.exists('queues:foo')
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
it 'can fetch by score' do
|
215
|
-
same_time = Time.now.to_f
|
216
|
-
add_retry('bob1', same_time)
|
217
|
-
add_retry('bob2', same_time)
|
218
|
-
r = Sidekiq::RetrySet.new
|
219
|
-
assert_equal 2, r.fetch(same_time).size
|
220
|
-
end
|
221
|
-
|
222
|
-
it 'can fetch by score and jid' do
|
223
|
-
same_time = Time.now.to_f
|
224
|
-
add_retry('bob1', same_time)
|
225
|
-
add_retry('bob2', same_time)
|
226
|
-
r = Sidekiq::RetrySet.new
|
227
|
-
# jobs = r.fetch(same_time)
|
228
|
-
# puts jobs[1].jid
|
229
|
-
assert_equal 1, r.fetch(same_time, 'bob1').size
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'shows empty retries' do
|
233
|
-
r = Sidekiq::RetrySet.new
|
234
|
-
assert_equal 0, r.size
|
235
|
-
end
|
236
|
-
|
237
|
-
it 'can enumerate retries' do
|
238
|
-
add_retry
|
239
|
-
|
240
|
-
r = Sidekiq::RetrySet.new
|
241
|
-
assert_equal 1, r.size
|
242
|
-
array = r.to_a
|
243
|
-
assert_equal 1, array.size
|
244
|
-
|
245
|
-
retri = array.first
|
246
|
-
assert_equal 'ApiWorker', retri.klass
|
247
|
-
assert_equal 'default', retri.queue
|
248
|
-
assert_equal 'bob', retri.jid
|
249
|
-
assert_in_delta Time.now.to_f, retri.at.to_f, 0.01
|
250
|
-
end
|
251
|
-
|
252
|
-
it 'can delete multiple retries from score' do
|
253
|
-
same_time = Time.now.to_f
|
254
|
-
add_retry('bob1', same_time)
|
255
|
-
add_retry('bob2', same_time)
|
256
|
-
r = Sidekiq::RetrySet.new
|
257
|
-
assert_equal 2, r.size
|
258
|
-
Sidekiq::RetrySet.new.delete(same_time)
|
259
|
-
assert_equal 0, r.size
|
260
|
-
end
|
261
|
-
|
262
|
-
it 'can delete a single retry from score and jid' do
|
263
|
-
same_time = Time.now.to_f
|
264
|
-
add_retry('bob1', same_time)
|
265
|
-
add_retry('bob2', same_time)
|
266
|
-
r = Sidekiq::RetrySet.new
|
267
|
-
assert_equal 2, r.size
|
268
|
-
Sidekiq::RetrySet.new.delete(same_time, 'bob1')
|
269
|
-
assert_equal 1, r.size
|
270
|
-
end
|
271
|
-
|
272
|
-
it 'can retry a retry' do
|
273
|
-
add_retry
|
274
|
-
r = Sidekiq::RetrySet.new
|
275
|
-
assert_equal 1, r.size
|
276
|
-
r.first.retry
|
277
|
-
assert_equal 0, r.size
|
278
|
-
assert_equal 1, Sidekiq::Queue.new('default').size
|
279
|
-
job = Sidekiq::Queue.new('default').first
|
280
|
-
assert_equal 'bob', job.jid
|
281
|
-
assert_equal 1, job['retry_count']
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'can clear retries' do
|
285
|
-
add_retry
|
286
|
-
add_retry('test')
|
287
|
-
r = Sidekiq::RetrySet.new
|
288
|
-
assert_equal 2, r.size
|
289
|
-
r.clear
|
290
|
-
assert_equal 0, r.size
|
291
|
-
end
|
292
|
-
|
293
|
-
it 'can enumerate workers' do
|
294
|
-
w = Sidekiq::Workers.new
|
295
|
-
assert_equal 0, w.size
|
296
|
-
w.each do
|
297
|
-
assert false
|
298
|
-
end
|
299
|
-
|
300
|
-
s = '12345'
|
301
|
-
data = Sidekiq.dump_json({ 'payload' => {}, 'queue' => 'default', 'run_at' => Time.now.to_i })
|
302
|
-
Sidekiq.redis do |c|
|
303
|
-
c.multi do
|
304
|
-
c.sadd('workers', s)
|
305
|
-
c.set("worker:#{s}", data)
|
306
|
-
c.set("worker:#{s}:started", Time.now.to_s)
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
assert_equal 1, w.size
|
311
|
-
w.each do |x, y, z|
|
312
|
-
assert_equal s, x
|
313
|
-
assert_equal 'default', y['queue']
|
314
|
-
assert_equal Time.now.year, DateTime.parse(z).year
|
315
|
-
end
|
316
|
-
end
|
317
|
-
|
318
|
-
it 'can reschedule jobs' do
|
319
|
-
add_retry('foo1')
|
320
|
-
add_retry('foo2')
|
321
|
-
|
322
|
-
retries = Sidekiq::RetrySet.new
|
323
|
-
assert_equal 2, retries.size
|
324
|
-
refute(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
|
325
|
-
|
326
|
-
retries.each do |retri|
|
327
|
-
retri.reschedule(Time.now.to_f + 10) if retri.jid == 'foo2'
|
328
|
-
end
|
329
|
-
|
330
|
-
assert_equal 2, retries.size
|
331
|
-
assert(retries.map { |r| r.score > (Time.now.to_f + 9) }.any?)
|
332
|
-
end
|
333
|
-
|
334
|
-
def add_retry(jid = 'bob', at = Time.now.to_f)
|
335
|
-
payload = Sidekiq.dump_json('class' => 'ApiWorker', 'args' => [1, 'mike'], 'queue' => 'default', 'jid' => jid, 'retry_count' => 2, 'failed_at' => Time.now.utc)
|
336
|
-
Sidekiq.redis do |conn|
|
337
|
-
conn.zadd('retry', at.to_s, payload)
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
end
|