sidekiq 4.1.4 → 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 +4 -4
- data/.github/issue_template.md +6 -1
- data/.travis.yml +9 -9
- data/Changes.md +100 -0
- data/Ent-Changes.md +51 -1
- data/Gemfile +6 -6
- data/Pro-Changes.md +69 -0
- data/README.md +4 -3
- data/Rakefile +5 -2
- data/bin/sidekiqload +11 -24
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
- data/lib/sidekiq/api.rb +21 -13
- data/lib/sidekiq/cli.rb +19 -5
- data/lib/sidekiq/core_ext.rb +13 -0
- data/lib/sidekiq/launcher.rb +36 -23
- data/lib/sidekiq/manager.rb +3 -2
- data/lib/sidekiq/middleware/server/logging.rb +8 -17
- data/lib/sidekiq/middleware/server/retry_jobs.rb +1 -1
- data/lib/sidekiq/processor.rb +31 -16
- data/lib/sidekiq/rails.rb +84 -0
- data/lib/sidekiq/redis_connection.rb +8 -1
- data/lib/sidekiq/scheduled.rb +1 -0
- data/lib/sidekiq/testing.rb +10 -2
- data/lib/sidekiq/util.rb +2 -1
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web/action.rb +93 -0
- data/lib/sidekiq/web/application.rb +336 -0
- data/lib/sidekiq/{web_helpers.rb → web/helpers.rb} +39 -16
- data/lib/sidekiq/web/router.rb +100 -0
- data/lib/sidekiq/web.rb +119 -184
- data/lib/sidekiq/worker.rb +3 -3
- data/lib/sidekiq.rb +7 -7
- data/sidekiq.gemspec +11 -5
- data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
- data/web/assets/javascripts/application.js +24 -20
- data/web/assets/javascripts/dashboard.js +1 -1
- data/web/assets/stylesheets/application.css +26 -1
- data/web/assets/stylesheets/bootstrap.css +4 -8
- data/web/locales/de.yml +1 -1
- data/web/locales/fa.yml +79 -0
- data/web/views/_footer.erb +1 -1
- data/web/views/_job_info.erb +1 -1
- data/web/views/busy.erb +2 -2
- data/web/views/dashboard.erb +4 -4
- data/web/views/dead.erb +1 -1
- data/web/views/layout.erb +3 -4
- data/web/views/morgue.erb +14 -10
- data/web/views/queue.erb +6 -6
- data/web/views/queues.erb +3 -3
- data/web/views/retries.erb +12 -10
- data/web/views/retry.erb +2 -2
- data/web/views/scheduled.erb +2 -2
- data/web/views/scheduled_job_info.erb +1 -1
- metadata +86 -129
- data/test/config.yml +0 -9
- data/test/env_based_config.yml +0 -11
- data/test/fake_env.rb +0 -1
- data/test/fixtures/en.yml +0 -2
- data/test/helper.rb +0 -75
- data/test/test_actors.rb +0 -138
- data/test/test_api.rb +0 -528
- data/test/test_cli.rb +0 -406
- data/test/test_client.rb +0 -266
- data/test/test_exception_handler.rb +0 -56
- data/test/test_extensions.rb +0 -127
- data/test/test_fetch.rb +0 -50
- data/test/test_launcher.rb +0 -85
- data/test/test_logging.rb +0 -35
- data/test/test_manager.rb +0 -50
- data/test/test_middleware.rb +0 -158
- data/test/test_processor.rb +0 -201
- data/test/test_rails.rb +0 -22
- data/test/test_redis_connection.rb +0 -132
- data/test/test_retry.rb +0 -326
- data/test/test_retry_exhausted.rb +0 -149
- data/test/test_scheduled.rb +0 -115
- data/test/test_scheduling.rb +0 -50
- data/test/test_sidekiq.rb +0 -107
- data/test/test_testing.rb +0 -143
- data/test/test_testing_fake.rb +0 -357
- data/test/test_testing_inline.rb +0 -94
- data/test/test_util.rb +0 -13
- data/test/test_web.rb +0 -614
- data/test/test_web_helpers.rb +0 -54
- 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.cs.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.cy.js +0 -20
- 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.nb.js +0 -18
- data/web/assets/javascripts/locales/jquery.timeago.nl.js +0 -20
- 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_js.erb +0 -5
data/lib/sidekiq/launcher.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
1
|
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
3
|
require 'sidekiq/manager'
|
4
4
|
require 'sidekiq/fetch'
|
5
5
|
require 'sidekiq/scheduled'
|
@@ -63,15 +63,16 @@ module Sidekiq
|
|
63
63
|
|
64
64
|
JVM_RESERVED_SIGNALS = ['USR1', 'USR2'] # Don't Process#kill if we get these signals via the API
|
65
65
|
|
66
|
-
def heartbeat
|
67
|
-
results = Sidekiq::CLI::PROCTITLES.map {|x| x.(self,
|
66
|
+
def heartbeat
|
67
|
+
results = Sidekiq::CLI::PROCTITLES.map {|x| x.(self, to_data) }
|
68
68
|
results.compact!
|
69
69
|
$0 = results.join(' ')
|
70
70
|
|
71
|
-
❤
|
71
|
+
❤
|
72
72
|
end
|
73
73
|
|
74
|
-
def ❤
|
74
|
+
def ❤
|
75
|
+
key = identity
|
75
76
|
fails = procd = 0
|
76
77
|
begin
|
77
78
|
Processor::FAILURE.update {|curr| fails = curr; 0 }
|
@@ -94,15 +95,19 @@ module Sidekiq
|
|
94
95
|
end
|
95
96
|
fails = procd = 0
|
96
97
|
|
97
|
-
_, _, _, msg = Sidekiq.redis do |conn|
|
98
|
+
_, exists, _, _, msg = Sidekiq.redis do |conn|
|
98
99
|
conn.multi do
|
99
100
|
conn.sadd('processes', key)
|
100
|
-
conn.
|
101
|
+
conn.exists(key)
|
102
|
+
conn.hmset(key, 'info', to_json, 'busy', Processor::WORKER_STATE.size, 'beat', Time.now.to_f, 'quiet', @done)
|
101
103
|
conn.expire(key, 60)
|
102
104
|
conn.rpop("#{key}-signals")
|
103
105
|
end
|
104
106
|
end
|
105
107
|
|
108
|
+
# first heartbeat or recovering from an outage and need to reestablish our heartbeat
|
109
|
+
fire_event(:heartbeat) if !exists
|
110
|
+
|
106
111
|
return unless msg
|
107
112
|
|
108
113
|
if JVM_RESERVED_SIGNALS.include?(msg)
|
@@ -120,28 +125,36 @@ module Sidekiq
|
|
120
125
|
end
|
121
126
|
|
122
127
|
def start_heartbeat
|
123
|
-
k = identity
|
124
|
-
data = {
|
125
|
-
'hostname' => hostname,
|
126
|
-
'started_at' => Time.now.to_f,
|
127
|
-
'pid' => $$,
|
128
|
-
'tag' => @options[:tag] || '',
|
129
|
-
'concurrency' => @options[:concurrency],
|
130
|
-
'queues' => @options[:queues].uniq,
|
131
|
-
'labels' => @options[:labels],
|
132
|
-
'identity' => k,
|
133
|
-
}
|
134
|
-
# this data doesn't change so dump it to a string
|
135
|
-
# now so we don't need to dump it every heartbeat.
|
136
|
-
json = Sidekiq.dump_json(data)
|
137
|
-
|
138
128
|
while true
|
139
|
-
heartbeat
|
129
|
+
heartbeat
|
140
130
|
sleep 5
|
141
131
|
end
|
142
132
|
Sidekiq.logger.info("Heartbeat stopping...")
|
143
133
|
end
|
144
134
|
|
135
|
+
def to_data
|
136
|
+
@data ||= begin
|
137
|
+
{
|
138
|
+
'hostname' => hostname,
|
139
|
+
'started_at' => Time.now.to_f,
|
140
|
+
'pid' => $$,
|
141
|
+
'tag' => @options[:tag] || '',
|
142
|
+
'concurrency' => @options[:concurrency],
|
143
|
+
'queues' => @options[:queues].uniq,
|
144
|
+
'labels' => @options[:labels],
|
145
|
+
'identity' => identity,
|
146
|
+
}
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def to_json
|
151
|
+
@json ||= begin
|
152
|
+
# this data changes infrequently so dump it to a string
|
153
|
+
# now so we don't need to dump it every heartbeat.
|
154
|
+
Sidekiq.dump_json(to_data)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
145
158
|
def clear_heartbeat
|
146
159
|
# Remove record from Redis since we are shutting down.
|
147
160
|
# Note we don't stop the heartbeat thread; if the process
|
data/lib/sidekiq/manager.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
1
|
# encoding: utf-8
|
2
|
+
# frozen_string_literal: true
|
3
3
|
require 'sidekiq/util'
|
4
4
|
require 'sidekiq/processor'
|
5
5
|
require 'sidekiq/fetch'
|
6
6
|
require 'thread'
|
7
|
+
require 'set'
|
7
8
|
|
8
9
|
module Sidekiq
|
9
10
|
|
10
11
|
##
|
11
12
|
# The Manager is the central coordination point in Sidekiq, controlling
|
12
|
-
# the lifecycle of the Processors
|
13
|
+
# the lifecycle of the Processors.
|
13
14
|
#
|
14
15
|
# Tasks:
|
15
16
|
#
|
@@ -4,28 +4,19 @@ module Sidekiq
|
|
4
4
|
class Logging
|
5
5
|
|
6
6
|
def call(worker, item, queue)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
raise
|
16
|
-
end
|
7
|
+
begin
|
8
|
+
start = Time.now
|
9
|
+
logger.info("start".freeze)
|
10
|
+
yield
|
11
|
+
logger.info("done: #{elapsed(start)} sec")
|
12
|
+
rescue Exception
|
13
|
+
logger.info("fail: #{elapsed(start)} sec")
|
14
|
+
raise
|
17
15
|
end
|
18
16
|
end
|
19
17
|
|
20
18
|
private
|
21
19
|
|
22
|
-
# If we're using a wrapper class, like ActiveJob, use the "wrapped"
|
23
|
-
# attribute to expose the underlying thing.
|
24
|
-
def log_context(worker, item)
|
25
|
-
klass = item['wrapped'.freeze] || worker.class.to_s
|
26
|
-
"#{klass} JID-#{item['jid'.freeze]}#{" BID-#{item['bid'.freeze]}" if item['bid'.freeze]}"
|
27
|
-
end
|
28
|
-
|
29
20
|
def elapsed(start)
|
30
21
|
(Time.now - start).round(3)
|
31
22
|
end
|
data/lib/sidekiq/processor.rb
CHANGED
@@ -36,6 +36,8 @@ module Sidekiq
|
|
36
36
|
@job = nil
|
37
37
|
@thread = nil
|
38
38
|
@strategy = (mgr.options[:fetch] || Sidekiq::BasicFetch).new(mgr.options)
|
39
|
+
@reloader = Sidekiq.options[:reloader]
|
40
|
+
@executor = Sidekiq.options[:executor]
|
39
41
|
end
|
40
42
|
|
41
43
|
def terminate(wait=false)
|
@@ -120,34 +122,47 @@ module Sidekiq
|
|
120
122
|
|
121
123
|
ack = false
|
122
124
|
begin
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
125
|
+
job_hash = Sidekiq.load_json(jobstr)
|
126
|
+
@reloader.call do
|
127
|
+
klass = job_hash['class'.freeze].constantize
|
128
|
+
worker = klass.new
|
129
|
+
worker.jid = job_hash['jid'.freeze]
|
130
|
+
|
131
|
+
stats(worker, job_hash, queue) do
|
132
|
+
Sidekiq::Logging.with_context(log_context(job_hash)) do
|
133
|
+
ack = true
|
134
|
+
Sidekiq.server_middleware.invoke(worker, job_hash, queue) do
|
135
|
+
@executor.call do
|
136
|
+
# Only ack if we either attempted to start this job or
|
137
|
+
# successfully completed it. This prevents us from
|
138
|
+
# losing jobs if a middleware raises an exception before yielding
|
139
|
+
execute_job(worker, cloned(job_hash['args'.freeze]))
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
135
143
|
end
|
144
|
+
ack = true
|
136
145
|
end
|
137
|
-
ack = true
|
138
146
|
rescue Sidekiq::Shutdown
|
139
147
|
# Had to force kill this job because it didn't finish
|
140
148
|
# within the timeout. Don't acknowledge the work since
|
141
149
|
# we didn't properly finish it.
|
142
150
|
ack = false
|
143
151
|
rescue Exception => ex
|
144
|
-
handle_exception(ex,
|
152
|
+
handle_exception(ex, { :context => "Job raised exception", :job => job_hash, :jobstr => jobstr })
|
145
153
|
raise
|
146
154
|
ensure
|
147
155
|
work.acknowledge if ack
|
148
156
|
end
|
149
157
|
end
|
150
158
|
|
159
|
+
# If we're using a wrapper class, like ActiveJob, use the "wrapped"
|
160
|
+
# attribute to expose the underlying thing.
|
161
|
+
def log_context(item)
|
162
|
+
klass = item['wrapped'.freeze] || item['class'.freeze]
|
163
|
+
"#{klass} JID-#{item['jid'.freeze]}#{" BID-#{item['bid'.freeze]}" if item['bid'.freeze]}"
|
164
|
+
end
|
165
|
+
|
151
166
|
def execute_job(worker, cloned_args)
|
152
167
|
worker.perform(*cloned_args)
|
153
168
|
end
|
@@ -160,9 +175,9 @@ module Sidekiq
|
|
160
175
|
PROCESSED = Concurrent::AtomicFixnum.new
|
161
176
|
FAILURE = Concurrent::AtomicFixnum.new
|
162
177
|
|
163
|
-
def stats(worker,
|
178
|
+
def stats(worker, job_hash, queue)
|
164
179
|
tid = thread_identity
|
165
|
-
WORKER_STATE[tid] = {:queue => queue, :payload =>
|
180
|
+
WORKER_STATE[tid] = {:queue => queue, :payload => cloned(job_hash), :run_at => Time.now.to_i }
|
166
181
|
|
167
182
|
begin
|
168
183
|
yield
|
data/lib/sidekiq/rails.rb
CHANGED
@@ -32,8 +32,92 @@ module Sidekiq
|
|
32
32
|
end
|
33
33
|
|
34
34
|
class Rails < ::Rails::Engine
|
35
|
+
# We need to setup this up before any application configuration which might
|
36
|
+
# change Sidekiq middleware.
|
37
|
+
#
|
38
|
+
# This hook happens after `Rails::Application` is inherited within
|
39
|
+
# config/application.rb and before config is touched, usually within the
|
40
|
+
# class block. Definitely before config/environments/*.rb and
|
41
|
+
# config/initializers/*.rb.
|
42
|
+
config.before_configuration do
|
43
|
+
if ::Rails::VERSION::MAJOR < 5 && defined?(::ActiveRecord)
|
44
|
+
Sidekiq.server_middleware do |chain|
|
45
|
+
require 'sidekiq/middleware/server/active_record'
|
46
|
+
chain.add Sidekiq::Middleware::Server::ActiveRecord
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
35
51
|
initializer 'sidekiq' do
|
36
52
|
Sidekiq.hook_rails!
|
37
53
|
end
|
54
|
+
|
55
|
+
config.after_initialize do
|
56
|
+
# This hook happens after all initializers are run, just before returning
|
57
|
+
# from config/environment.rb back to sidekiq/cli.rb.
|
58
|
+
# We have to add the reloader after initialize to see if cache_classes has
|
59
|
+
# been turned on.
|
60
|
+
#
|
61
|
+
# None of this matters on the client-side, only within the Sidekiq process itself.
|
62
|
+
#
|
63
|
+
Sidekiq.configure_server do |_|
|
64
|
+
if ::Rails::VERSION::MAJOR >= 5
|
65
|
+
# The reloader also takes care of ActiveRecord but is incompatible with
|
66
|
+
# the ActiveRecord middleware so make sure it's not in the chain already.
|
67
|
+
if defined?(Sidekiq::Middleware::Server::ActiveRecord) && Sidekiq.server_middleware.exists?(Sidekiq::Middleware::Server::ActiveRecord)
|
68
|
+
raise ArgumentError, "You are using the Sidekiq ActiveRecord middleware and the new Rails 5 reloader which are incompatible. Please remove the ActiveRecord middleware from your Sidekiq middleware configuration."
|
69
|
+
elsif ::Rails.application.config.cache_classes
|
70
|
+
# The reloader API has proven to be troublesome under load in production.
|
71
|
+
# We won't use it at all when classes are cached, see #3154
|
72
|
+
Sidekiq.logger.debug { "Autoload disabled in #{::Rails.env}, Sidekiq will not reload changed classes" }
|
73
|
+
Sidekiq.options[:executor] = Sidekiq::Rails::Executor.new
|
74
|
+
else
|
75
|
+
Sidekiq.logger.debug { "Enabling Rails 5+ live code reloading, so hot!" }
|
76
|
+
Sidekiq.options[:reloader] = Sidekiq::Rails::Reloader.new
|
77
|
+
Psych::Visitors::ToRuby.prepend(Sidekiq::Rails::PsychAutoload)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class Executor
|
84
|
+
def initialize(app = ::Rails.application)
|
85
|
+
@app = app
|
86
|
+
end
|
87
|
+
|
88
|
+
def call
|
89
|
+
@app.executor.wrap do
|
90
|
+
yield
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def inspect
|
95
|
+
"#<Sidekiq::Rails::Executor @app=#{@app.class.name}>"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
class Reloader
|
100
|
+
def initialize(app = ::Rails.application)
|
101
|
+
@app = app
|
102
|
+
end
|
103
|
+
|
104
|
+
def call
|
105
|
+
@app.reloader.wrap do
|
106
|
+
yield
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def inspect
|
111
|
+
"#<Sidekiq::Rails::Reloader @app=#{@app.class.name}>"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
module PsychAutoload
|
116
|
+
def resolve_class(klass_name)
|
117
|
+
klass_name && klass_name.constantize
|
118
|
+
rescue NameError
|
119
|
+
super
|
120
|
+
end
|
121
|
+
end
|
38
122
|
end if defined?(::Rails)
|
39
123
|
end
|
@@ -67,7 +67,14 @@ module Sidekiq
|
|
67
67
|
opts.delete(:network_timeout)
|
68
68
|
end
|
69
69
|
|
70
|
-
opts[:driver]
|
70
|
+
opts[:driver] ||= 'ruby'
|
71
|
+
|
72
|
+
# Issue #3303, redis-rb will silently retry an operation.
|
73
|
+
# This can lead to duplicate jobs if Sidekiq::Client's LPUSH
|
74
|
+
# is performed twice but I believe this is much, much rarer
|
75
|
+
# than the reconnect silently fixing a problem; we keep it
|
76
|
+
# on by default.
|
77
|
+
opts[:reconnect_attempts] ||= 1
|
71
78
|
|
72
79
|
opts
|
73
80
|
end
|
data/lib/sidekiq/scheduled.rb
CHANGED
data/lib/sidekiq/testing.rb
CHANGED
@@ -69,7 +69,9 @@ module Sidekiq
|
|
69
69
|
def raw_push(payloads)
|
70
70
|
if Sidekiq::Testing.fake?
|
71
71
|
payloads.each do |job|
|
72
|
-
|
72
|
+
job = Sidekiq.load_json(Sidekiq.dump_json(job))
|
73
|
+
job.merge!('enqueued_at' => Time.now.to_f) unless job['at']
|
74
|
+
Queues.push(job['queue'], job['class'], job)
|
73
75
|
end
|
74
76
|
true
|
75
77
|
elsif Sidekiq::Testing.inline?
|
@@ -264,7 +266,7 @@ module Sidekiq
|
|
264
266
|
def drain
|
265
267
|
while jobs.any?
|
266
268
|
next_job = jobs.first
|
267
|
-
Queues.delete_for(next_job["jid"], queue, self.to_s)
|
269
|
+
Queues.delete_for(next_job["jid"], next_job["queue"], self.to_s)
|
268
270
|
process_job(next_job)
|
269
271
|
end
|
270
272
|
end
|
@@ -314,3 +316,9 @@ module Sidekiq
|
|
314
316
|
end
|
315
317
|
end
|
316
318
|
end
|
319
|
+
|
320
|
+
if defined?(::Rails) && !Rails.env.test?
|
321
|
+
puts("**************************************************")
|
322
|
+
puts("⛔️ WARNING: Sidekiq testing API enabled, but this is not the test environment. Your jobs will not go to Redis.")
|
323
|
+
puts("**************************************************")
|
324
|
+
end
|
data/lib/sidekiq/util.rb
CHANGED
@@ -22,6 +22,7 @@ module Sidekiq
|
|
22
22
|
|
23
23
|
def safe_thread(name, &block)
|
24
24
|
Thread.new do
|
25
|
+
Thread.current['sidekiq_label'] = name
|
25
26
|
watchdog(name, &block)
|
26
27
|
end
|
27
28
|
end
|
@@ -53,7 +54,7 @@ module Sidekiq
|
|
53
54
|
begin
|
54
55
|
block.call
|
55
56
|
rescue => ex
|
56
|
-
handle_exception(ex, { event: event })
|
57
|
+
handle_exception(ex, { context: "Exception during Sidekiq lifecycle event.", event: event })
|
57
58
|
end
|
58
59
|
end
|
59
60
|
arr.clear
|
data/lib/sidekiq/version.rb
CHANGED
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sidekiq
|
4
|
+
class WebAction
|
5
|
+
RACK_SESSION = 'rack.session'.freeze
|
6
|
+
|
7
|
+
attr_accessor :env, :block, :type
|
8
|
+
|
9
|
+
def settings
|
10
|
+
Web.settings
|
11
|
+
end
|
12
|
+
|
13
|
+
def request
|
14
|
+
@request ||= ::Rack::Request.new(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
def halt(res)
|
18
|
+
throw :halt, res
|
19
|
+
end
|
20
|
+
|
21
|
+
def redirect(location)
|
22
|
+
throw :halt, [302, { "Location" => "#{request.base_url}#{location}" }, []]
|
23
|
+
end
|
24
|
+
|
25
|
+
def params
|
26
|
+
indifferent_hash = Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
|
27
|
+
|
28
|
+
indifferent_hash.merge! request.params
|
29
|
+
route_params.each {|k,v| indifferent_hash[k.to_s] = v }
|
30
|
+
|
31
|
+
indifferent_hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def route_params
|
35
|
+
env[WebRouter::ROUTE_PARAMS]
|
36
|
+
end
|
37
|
+
|
38
|
+
def session
|
39
|
+
env[RACK_SESSION]
|
40
|
+
end
|
41
|
+
|
42
|
+
def content_type(type)
|
43
|
+
@type = type
|
44
|
+
end
|
45
|
+
|
46
|
+
def erb(content, options = {})
|
47
|
+
if content.kind_of? Symbol
|
48
|
+
unless respond_to?(:"_erb_#{content}")
|
49
|
+
src = ERB.new(File.read("#{Web.settings.views}/#{content}.erb")).src
|
50
|
+
WebAction.class_eval("def _erb_#{content}\n#{src}\n end")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
if @_erb
|
55
|
+
_erb(content, options[:locals])
|
56
|
+
else
|
57
|
+
@_erb = true
|
58
|
+
content = _erb(content, options[:locals])
|
59
|
+
|
60
|
+
_render { content }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def render(engine, content, options = {})
|
65
|
+
raise "Only erb templates are supported" if engine != :erb
|
66
|
+
|
67
|
+
erb(content, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def json(payload)
|
71
|
+
[200, { "Content-Type" => "application/json", "Cache-Control" => "no-cache" }, [Sidekiq.dump_json(payload)]]
|
72
|
+
end
|
73
|
+
|
74
|
+
def initialize(env, block)
|
75
|
+
@_erb = false
|
76
|
+
@env = env
|
77
|
+
@block = block
|
78
|
+
@@files ||= {}
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def _erb(file, locals)
|
84
|
+
locals.each {|k, v| define_singleton_method(k){ v } } if locals
|
85
|
+
|
86
|
+
if file.kind_of?(String)
|
87
|
+
ERB.new(file).result(binding)
|
88
|
+
else
|
89
|
+
send(:"_erb_#{file}")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|