sidekiq 4.1.4 → 4.2.0
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/.travis.yml +0 -6
- data/Changes.md +24 -0
- data/Ent-Changes.md +24 -1
- data/Gemfile +5 -5
- data/Pro-Changes.md +11 -0
- data/lib/sidekiq.rb +4 -1
- data/lib/sidekiq/cli.rb +11 -2
- data/lib/sidekiq/launcher.rb +5 -1
- data/lib/sidekiq/manager.rb +1 -0
- data/lib/sidekiq/processor.rb +28 -25
- data/lib/sidekiq/rails.rb +17 -0
- data/lib/sidekiq/scheduled.rb +1 -0
- data/lib/sidekiq/version.rb +1 -1
- data/lib/sidekiq/web.rb +79 -202
- data/lib/sidekiq/web/action.rb +99 -0
- data/lib/sidekiq/web/application.rb +335 -0
- data/lib/sidekiq/{web_helpers.rb → web/helpers.rb} +29 -10
- data/lib/sidekiq/web/router.rb +96 -0
- data/sidekiq.gemspec +2 -2
- data/test/test_cli.rb +14 -2
- data/test/test_launcher.rb +12 -2
- data/test/test_web.rb +52 -5
- data/web/assets/images/{status-sd8051fd480.png → status.png} +0 -0
- data/web/assets/javascripts/application.js +5 -0
- 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/views/_footer.erb +1 -1
- data/web/views/busy.erb +2 -2
- data/web/views/dashboard.erb +2 -2
- data/web/views/dead.erb +1 -1
- data/web/views/layout.erb +3 -3
- data/web/views/morgue.erb +2 -2
- data/web/views/queue.erb +3 -3
- data/web/views/queues.erb +1 -1
- data/web/views/retries.erb +2 -2
- data/web/views/retry.erb +1 -1
- data/web/views/scheduled.erb +2 -2
- data/web/views/scheduled_job_info.erb +1 -1
- metadata +12 -20
- 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/views/_poll_js.erb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db0f25c2fe7ea87588364c3eb86e3b929197139c
|
4
|
+
data.tar.gz: 8fa8c056e6c5fad50ce5d49838515aca61573458
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a801ac5f3d70ca6e1856cb7369f557d5bb8d1c579e775f6a4f5ed97d534af2d289f884979de978f3a7cab2d1261fabeef6b7fc9e73b1684c7b1daabbd25e0e7
|
7
|
+
data.tar.gz: 37c617e0ea241fe8cea7c85e6479e2259e06f1b5bfb06ce811b2529d73adc8a09a67655dbdcaff028ba4cd3226169a79f636f813f7848d7fe8eaa084ea9d5739
|
data/.travis.yml
CHANGED
data/Changes.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# Sidekiq Changes
|
2
2
|
|
3
|
+
4.2.0
|
4
|
+
-----------
|
5
|
+
|
6
|
+
- Enable development-mode code reloading. **With Rails 5.0+, you don't need
|
7
|
+
to restart Sidekiq to pick up your Sidekiq::Worker changes anymore!** [#2457]
|
8
|
+
- **Remove Sinatra dependency**. Sidekiq's Web UI now uses Rack directly.
|
9
|
+
Thank you to Sidekiq's newest committer, **badosu**, for writing the code
|
10
|
+
and doing a lot of testing to ensure compatibility with many different
|
11
|
+
3rd party plugins. If your Web UI works with 4.1.4 but fails with
|
12
|
+
4.2.0, please open an issue. [#3075]
|
13
|
+
- Allow tuning of concurrency with the `RAILS_MAX_THREADS` env var. [#2985]
|
14
|
+
This is the same var used by Puma so you can tune all of your systems
|
15
|
+
the same way:
|
16
|
+
```sh
|
17
|
+
web: RAILS_MAX_THREADS=5 bundle exec puma ...
|
18
|
+
worker: RAILS_MAX_THREADS=10 bundle exec sidekiq ...
|
19
|
+
```
|
20
|
+
Using `-c` or `config/sidekiq.yml` overrides this setting. I recommend
|
21
|
+
adjusting your `config/database.yml` to use it too so connections are
|
22
|
+
auto-scaled:
|
23
|
+
```yaml
|
24
|
+
pool: <%= ENV['RAILS_MAX_THREADS'] || 5 %>
|
25
|
+
```
|
26
|
+
|
3
27
|
4.1.4
|
4
28
|
-----------
|
5
29
|
|
data/Ent-Changes.md
CHANGED
@@ -3,7 +3,30 @@ Sidekiq Enterprise Changelog
|
|
3
3
|
|
4
4
|
Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
|
5
5
|
|
6
|
-
|
6
|
+
1.3.2
|
7
|
+
-------------
|
8
|
+
|
9
|
+
- Upgrade encryption to use OpenSSL's more secure GCM mode. [#3060]
|
10
|
+
|
11
|
+
1.3.1
|
12
|
+
-------------
|
13
|
+
|
14
|
+
- Fix multi-process memory monitoring on CentOS 6.x [#3063]
|
15
|
+
- Polish the new encryption feature a bit.
|
16
|
+
|
17
|
+
1.3.0
|
18
|
+
-------------
|
19
|
+
|
20
|
+
- **BETA** [New encryption feature](https://github.com/mperham/sidekiq/wiki/Ent-Encryption)
|
21
|
+
which automatically encrypts the last argument of a Worker, aka the secret bag.
|
22
|
+
|
23
|
+
1.2.4
|
24
|
+
-------------
|
25
|
+
|
26
|
+
- Fix issue causing some minutely jobs to execute every other minute.
|
27
|
+
- Log a warning if slow periodic processing causes us to miss a clock tick.
|
28
|
+
|
29
|
+
1.2.3
|
7
30
|
-------------
|
8
31
|
|
9
32
|
- Periodic jobs could stop executing until process restart if Redis goes down [#3047]
|
data/Gemfile
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
gemspec
|
3
3
|
|
4
|
+
gem 'rails', '5.0.0'
|
4
5
|
gem "hiredis"
|
5
|
-
gem 'rails', '~> 4.2'
|
6
6
|
gem 'simplecov'
|
7
7
|
gem 'minitest'
|
8
8
|
gem 'minitest-utils'
|
@@ -23,7 +23,7 @@ platforms :mri do
|
|
23
23
|
gem 'ruby-prof'
|
24
24
|
end
|
25
25
|
|
26
|
-
platforms :jruby do
|
27
|
-
gem 'jruby-openssl'
|
28
|
-
gem 'activerecord-jdbcsqlite3-adapter'
|
29
|
-
end
|
26
|
+
#platforms :jruby do
|
27
|
+
#gem 'jruby-openssl'
|
28
|
+
#gem 'activerecord-jdbcsqlite3-adapter'
|
29
|
+
#end
|
data/Pro-Changes.md
CHANGED
@@ -3,6 +3,17 @@ Sidekiq Pro Changelog
|
|
3
3
|
|
4
4
|
Please see [http://sidekiq.org/](http://sidekiq.org/) for more details and how to buy.
|
5
5
|
|
6
|
+
3.3.3
|
7
|
+
---------
|
8
|
+
|
9
|
+
- Update Web UI extension to work with Sidekiq 4.2.0's new Web UI. [#3075]
|
10
|
+
|
11
|
+
3.3.2
|
12
|
+
---------
|
13
|
+
|
14
|
+
- Minimize batch memory usage after success [#3083]
|
15
|
+
- Extract batch's 24 hr linger expiry to a LINGER constant so it can be tuned. [#3011]
|
16
|
+
|
6
17
|
3.3.1
|
7
18
|
---------
|
8
19
|
|
data/lib/sidekiq.rb
CHANGED
@@ -28,9 +28,11 @@ module Sidekiq
|
|
28
28
|
startup: [],
|
29
29
|
quiet: [],
|
30
30
|
shutdown: [],
|
31
|
+
heartbeat: [],
|
31
32
|
},
|
32
33
|
dead_max_jobs: 10_000,
|
33
|
-
dead_timeout_in_seconds: 180 * 24 * 60 * 60 # 6 months
|
34
|
+
dead_timeout_in_seconds: 180 * 24 * 60 * 60, # 6 months
|
35
|
+
reloader: proc { |&block| block.call },
|
34
36
|
}
|
35
37
|
|
36
38
|
DEFAULT_WORKER_OPTIONS = {
|
@@ -169,6 +171,7 @@ module Sidekiq
|
|
169
171
|
def self.default_retries_exhausted=(prok)
|
170
172
|
@default_retries_exhausted = prok
|
171
173
|
end
|
174
|
+
@default_retries_exhausted = ->(job, ex) { }
|
172
175
|
def self.default_retries_exhausted
|
173
176
|
@default_retries_exhausted
|
174
177
|
end
|
data/lib/sidekiq/cli.rb
CHANGED
@@ -208,6 +208,8 @@ module Sidekiq
|
|
208
208
|
opts = parse_config(cfile).merge(opts) if cfile
|
209
209
|
|
210
210
|
opts[:strict] = true if opts[:strict].nil?
|
211
|
+
opts[:concurrency] = Integer(ENV["RAILS_MAX_THREADS"]) if !opts[:concurrency] && ENV["RAILS_MAX_THREADS"]
|
212
|
+
opts[:identity] = identity
|
211
213
|
|
212
214
|
options.merge!(opts)
|
213
215
|
end
|
@@ -227,7 +229,7 @@ module Sidekiq
|
|
227
229
|
require 'sidekiq/rails'
|
228
230
|
require File.expand_path("#{options[:require]}/config/environment.rb")
|
229
231
|
::Rails.application.eager_load!
|
230
|
-
|
232
|
+
elsif ::Rails::VERSION::MAJOR == 4
|
231
233
|
# Painful contortions, see 1791 for discussion
|
232
234
|
require File.expand_path("#{options[:require]}/config/application.rb")
|
233
235
|
::Rails::Application.initializer "sidekiq.eager_load" do
|
@@ -235,10 +237,17 @@ module Sidekiq
|
|
235
237
|
end
|
236
238
|
require 'sidekiq/rails'
|
237
239
|
require File.expand_path("#{options[:require]}/config/environment.rb")
|
240
|
+
else
|
241
|
+
require 'sidekiq/rails'
|
242
|
+
require File.expand_path("#{options[:require]}/config/environment.rb")
|
243
|
+
Sidekiq.options[:reloader] = Sidekiq::Rails::Reloader.new
|
238
244
|
end
|
239
245
|
options[:tag] ||= default_tag
|
240
246
|
else
|
241
|
-
|
247
|
+
not_required_message = "#{options[:require]} was not required, you should use an explicit path: " +
|
248
|
+
"./#{options[:require]} or /path/to/#{options[:require]}"
|
249
|
+
|
250
|
+
require(options[:require]) || raise(ArgumentError, not_required_message)
|
242
251
|
end
|
243
252
|
end
|
244
253
|
|
data/lib/sidekiq/launcher.rb
CHANGED
@@ -94,15 +94,19 @@ module Sidekiq
|
|
94
94
|
end
|
95
95
|
fails = procd = 0
|
96
96
|
|
97
|
-
_, _, _, msg = Sidekiq.redis do |conn|
|
97
|
+
_, exists, _, _, msg = Sidekiq.redis do |conn|
|
98
98
|
conn.multi do
|
99
99
|
conn.sadd('processes', key)
|
100
|
+
conn.exists(key)
|
100
101
|
conn.hmset(key, 'info', json, 'busy', Processor::WORKER_STATE.size, 'beat', Time.now.to_f, 'quiet', @done)
|
101
102
|
conn.expire(key, 60)
|
102
103
|
conn.rpop("#{key}-signals")
|
103
104
|
end
|
104
105
|
end
|
105
106
|
|
107
|
+
# first heartbeat or recovering from an outage and need to reestablish our heartbeat
|
108
|
+
fire_event(:heartbeat) if !exists
|
109
|
+
|
106
110
|
return unless msg
|
107
111
|
|
108
112
|
if JVM_RESERVED_SIGNALS.include?(msg)
|
data/lib/sidekiq/manager.rb
CHANGED
data/lib/sidekiq/processor.rb
CHANGED
@@ -36,6 +36,7 @@ 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]
|
39
40
|
end
|
40
41
|
|
41
42
|
def terminate(wait=false)
|
@@ -118,33 +119,35 @@ module Sidekiq
|
|
118
119
|
jobstr = work.job
|
119
120
|
queue = work.queue_name
|
120
121
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
122
|
+
@reloader.call do
|
123
|
+
ack = false
|
124
|
+
begin
|
125
|
+
job = Sidekiq.load_json(jobstr)
|
126
|
+
klass = job['class'.freeze].constantize
|
127
|
+
worker = klass.new
|
128
|
+
worker.jid = job['jid'.freeze]
|
129
|
+
|
130
|
+
stats(worker, job, queue) do
|
131
|
+
Sidekiq.server_middleware.invoke(worker, job, queue) do
|
132
|
+
# Only ack if we either attempted to start this job or
|
133
|
+
# successfully completed it. This prevents us from
|
134
|
+
# losing jobs if a middleware raises an exception before yielding
|
135
|
+
ack = true
|
136
|
+
execute_job(worker, cloned(job['args'.freeze]))
|
137
|
+
end
|
135
138
|
end
|
139
|
+
ack = true
|
140
|
+
rescue Sidekiq::Shutdown
|
141
|
+
# Had to force kill this job because it didn't finish
|
142
|
+
# within the timeout. Don't acknowledge the work since
|
143
|
+
# we didn't properly finish it.
|
144
|
+
ack = false
|
145
|
+
rescue Exception => ex
|
146
|
+
handle_exception(ex, job || { :job => jobstr })
|
147
|
+
raise
|
148
|
+
ensure
|
149
|
+
work.acknowledge if ack
|
136
150
|
end
|
137
|
-
ack = true
|
138
|
-
rescue Sidekiq::Shutdown
|
139
|
-
# Had to force kill this job because it didn't finish
|
140
|
-
# within the timeout. Don't acknowledge the work since
|
141
|
-
# we didn't properly finish it.
|
142
|
-
ack = false
|
143
|
-
rescue Exception => ex
|
144
|
-
handle_exception(ex, job || { :job => jobstr })
|
145
|
-
raise
|
146
|
-
ensure
|
147
|
-
work.acknowledge if ack
|
148
151
|
end
|
149
152
|
end
|
150
153
|
|
data/lib/sidekiq/rails.rb
CHANGED
@@ -35,5 +35,22 @@ module Sidekiq
|
|
35
35
|
initializer 'sidekiq' do
|
36
36
|
Sidekiq.hook_rails!
|
37
37
|
end
|
38
|
+
|
39
|
+
class Reloader
|
40
|
+
def initialize(app = ::Rails.application)
|
41
|
+
Sidekiq.logger.debug "Enabling Rails 5+ live code reloading, so hot!" unless app.config.cache_classes
|
42
|
+
@app = app
|
43
|
+
end
|
44
|
+
|
45
|
+
def call
|
46
|
+
@app.reloader.wrap do
|
47
|
+
yield
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def inspect
|
52
|
+
"#<Sidekiq::Rails::Reloader @app=#{@app.class.name}>"
|
53
|
+
end
|
54
|
+
end
|
38
55
|
end if defined?(::Rails)
|
39
56
|
end
|
data/lib/sidekiq/scheduled.rb
CHANGED
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web.rb
CHANGED
@@ -1,26 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'erb'
|
3
|
-
require 'yaml'
|
4
|
-
require 'sinatra/base'
|
5
3
|
|
6
4
|
require 'sidekiq'
|
7
5
|
require 'sidekiq/api'
|
8
6
|
require 'sidekiq/paginator'
|
9
|
-
require 'sidekiq/
|
7
|
+
require 'sidekiq/web/helpers'
|
10
8
|
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
require 'sidekiq/web/router'
|
10
|
+
require 'sidekiq/web/action'
|
11
|
+
require 'sidekiq/web/application'
|
14
12
|
|
15
|
-
|
16
|
-
use ::Rack::Protection, :use => :authenticity_token unless ENV['RACK_ENV'] == 'test'
|
13
|
+
require 'rack/protection'
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
set :locales, ["#{root}/locales"]
|
15
|
+
require 'rack/builder'
|
16
|
+
require 'rack/file'
|
17
|
+
require 'rack/session/cookie'
|
22
18
|
|
23
|
-
|
19
|
+
module Sidekiq
|
20
|
+
class Web
|
21
|
+
ROOT = File.expand_path("#{File.dirname(__FILE__)}/../../web")
|
22
|
+
VIEWS = "#{ROOT}/views".freeze
|
23
|
+
LOCALES = ["#{ROOT}/locales".freeze]
|
24
|
+
LAYOUT = "#{VIEWS}/layout.erb".freeze
|
25
|
+
ASSETS = "#{ROOT}/assets".freeze
|
24
26
|
|
25
27
|
DEFAULT_TABS = {
|
26
28
|
"Dashboard" => '',
|
@@ -32,6 +34,18 @@ module Sidekiq
|
|
32
34
|
}
|
33
35
|
|
34
36
|
class << self
|
37
|
+
def settings
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def middlewares
|
42
|
+
@middlewares ||= []
|
43
|
+
end
|
44
|
+
|
45
|
+
def use(*middleware_args, &block)
|
46
|
+
middlewares << [middleware_args, block]
|
47
|
+
end
|
48
|
+
|
35
49
|
def default_tabs
|
36
50
|
DEFAULT_TABS
|
37
51
|
end
|
@@ -41,234 +55,97 @@ module Sidekiq
|
|
41
55
|
end
|
42
56
|
alias_method :tabs, :custom_tabs
|
43
57
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
get "/busy" do
|
48
|
-
erb :busy
|
49
|
-
end
|
50
|
-
|
51
|
-
post "/busy" do
|
52
|
-
if params['identity']
|
53
|
-
p = Sidekiq::Process.new('identity' => params['identity'])
|
54
|
-
p.quiet! if params[:quiet]
|
55
|
-
p.stop! if params[:stop]
|
56
|
-
else
|
57
|
-
processes.each do |pro|
|
58
|
-
pro.quiet! if params[:quiet]
|
59
|
-
pro.stop! if params[:stop]
|
60
|
-
end
|
58
|
+
def locales
|
59
|
+
@locales ||= LOCALES
|
61
60
|
end
|
62
|
-
redirect "#{root_path}busy"
|
63
|
-
end
|
64
61
|
|
65
|
-
|
66
|
-
|
67
|
-
erb :queues
|
68
|
-
end
|
69
|
-
|
70
|
-
get "/queues/:name" do
|
71
|
-
halt 404 unless params[:name]
|
72
|
-
@count = (params[:count] || 25).to_i
|
73
|
-
@name = params[:name]
|
74
|
-
@queue = Sidekiq::Queue.new(@name)
|
75
|
-
(@current_page, @total_size, @messages) = page("queue:#{@name}", params[:page], @count)
|
76
|
-
@messages = @messages.map { |msg| Sidekiq::Job.new(msg, @name) }
|
77
|
-
erb :queue
|
78
|
-
end
|
79
|
-
|
80
|
-
post "/queues/:name" do
|
81
|
-
Sidekiq::Queue.new(params[:name]).clear
|
82
|
-
redirect "#{root_path}queues"
|
83
|
-
end
|
84
|
-
|
85
|
-
post "/queues/:name/delete" do
|
86
|
-
Sidekiq::Job.new(params[:key_val], params[:name]).delete
|
87
|
-
redirect_with_query("#{root_path}queues/#{params[:name]}")
|
88
|
-
end
|
89
|
-
|
90
|
-
get '/morgue' do
|
91
|
-
@count = (params[:count] || 25).to_i
|
92
|
-
(@current_page, @total_size, @dead) = page("dead", params[:page], @count, reverse: true)
|
93
|
-
@dead = @dead.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
94
|
-
erb :morgue
|
95
|
-
end
|
96
|
-
|
97
|
-
get "/morgue/:key" do
|
98
|
-
halt 404 unless params['key']
|
99
|
-
@dead = Sidekiq::DeadSet.new.fetch(*parse_params(params['key'])).first
|
100
|
-
redirect "#{root_path}morgue" if @dead.nil?
|
101
|
-
erb :dead
|
102
|
-
end
|
103
|
-
|
104
|
-
post '/morgue' do
|
105
|
-
redirect request.path unless params['key']
|
106
|
-
|
107
|
-
params['key'].each do |key|
|
108
|
-
job = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
|
109
|
-
retry_or_delete_or_kill job, params if job
|
62
|
+
def views
|
63
|
+
@views ||= VIEWS
|
110
64
|
end
|
111
|
-
redirect_with_query("#{root_path}morgue")
|
112
|
-
end
|
113
65
|
|
114
|
-
|
115
|
-
|
116
|
-
redirect "#{root_path}morgue"
|
66
|
+
attr_accessor :app_url, :session_secret, :redis_pool
|
67
|
+
attr_writer :locales, :views
|
117
68
|
end
|
118
69
|
|
119
|
-
|
120
|
-
|
121
|
-
redirect "#{root_path}morgue"
|
70
|
+
def settings
|
71
|
+
self.class.settings
|
122
72
|
end
|
123
73
|
|
124
|
-
|
125
|
-
|
126
|
-
job = Sidekiq::DeadSet.new.fetch(*parse_params(params['key'])).first
|
127
|
-
retry_or_delete_or_kill job, params if job
|
128
|
-
redirect_with_query("#{root_path}morgue")
|
74
|
+
def use(*middleware_args, &block)
|
75
|
+
middlewares << [middleware_args, block]
|
129
76
|
end
|
130
77
|
|
131
|
-
|
132
|
-
|
133
|
-
@count = (params[:count] || 25).to_i
|
134
|
-
(@current_page, @total_size, @retries) = page("retry", params[:page], @count)
|
135
|
-
@retries = @retries.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
136
|
-
erb :retries
|
137
|
-
end
|
138
|
-
|
139
|
-
get "/retries/:key" do
|
140
|
-
@retry = Sidekiq::RetrySet.new.fetch(*parse_params(params['key'])).first
|
141
|
-
redirect "#{root_path}retries" if @retry.nil?
|
142
|
-
erb :retry
|
143
|
-
end
|
144
|
-
|
145
|
-
post '/retries' do
|
146
|
-
redirect request.path unless params['key']
|
147
|
-
|
148
|
-
params['key'].each do |key|
|
149
|
-
job = Sidekiq::RetrySet.new.fetch(*parse_params(key)).first
|
150
|
-
retry_or_delete_or_kill job, params if job
|
151
|
-
end
|
152
|
-
redirect_with_query("#{root_path}retries")
|
78
|
+
def middlewares
|
79
|
+
@middlewares ||= Web.middlewares.dup
|
153
80
|
end
|
154
81
|
|
155
|
-
|
156
|
-
|
157
|
-
redirect "#{root_path}retries"
|
82
|
+
def call(env)
|
83
|
+
app.call(env)
|
158
84
|
end
|
159
85
|
|
160
|
-
|
161
|
-
|
162
|
-
|
86
|
+
def self.call(env)
|
87
|
+
@app ||= new
|
88
|
+
@app.call(env)
|
163
89
|
end
|
164
90
|
|
165
|
-
|
166
|
-
|
167
|
-
retry_or_delete_or_kill job, params if job
|
168
|
-
redirect_with_query("#{root_path}retries")
|
91
|
+
def app
|
92
|
+
@app ||= build
|
169
93
|
end
|
170
94
|
|
171
|
-
|
172
|
-
|
173
|
-
(@current_page, @total_size, @scheduled) = page("schedule", params[:page], @count)
|
174
|
-
@scheduled = @scheduled.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
175
|
-
erb :scheduled
|
95
|
+
def self.register(extension)
|
96
|
+
extension.registered(WebApplication)
|
176
97
|
end
|
177
98
|
|
178
|
-
|
179
|
-
@job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
|
180
|
-
redirect "#{root_path}scheduled" if @job.nil?
|
181
|
-
erb :scheduled_job_info
|
182
|
-
end
|
183
|
-
|
184
|
-
post '/scheduled' do
|
185
|
-
redirect request.path unless params['key']
|
99
|
+
private
|
186
100
|
|
187
|
-
|
188
|
-
|
189
|
-
|
101
|
+
def using?(middleware)
|
102
|
+
middlewares.any? do |(m,_)|
|
103
|
+
m.kind_of?(Array) && (m[0] == middleware || m[0].kind_of?(middleware))
|
190
104
|
end
|
191
|
-
redirect_with_query("#{root_path}scheduled")
|
192
|
-
end
|
193
|
-
|
194
|
-
post "/scheduled/:key" do
|
195
|
-
halt 404 unless params['key']
|
196
|
-
job = Sidekiq::ScheduledSet.new.fetch(*parse_params(params['key'])).first
|
197
|
-
delete_or_add_queue job, params if job
|
198
|
-
redirect_with_query("#{root_path}scheduled")
|
199
|
-
end
|
200
|
-
|
201
|
-
get '/' do
|
202
|
-
@redis_info = redis_info.select{ |k, v| REDIS_KEYS.include? k }
|
203
|
-
stats_history = Sidekiq::Stats::History.new((params[:days] || 30).to_i)
|
204
|
-
@processed_history = stats_history.processed
|
205
|
-
@failed_history = stats_history.failed
|
206
|
-
erb :dashboard
|
207
105
|
end
|
208
106
|
|
209
|
-
|
107
|
+
def build
|
108
|
+
middlewares = self.middlewares
|
109
|
+
klass = self.class
|
210
110
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
get '/stats' do
|
216
|
-
sidekiq_stats = Sidekiq::Stats.new
|
217
|
-
redis_stats = redis_info.select { |k, v| REDIS_KEYS.include? k }
|
218
|
-
|
219
|
-
content_type :json
|
220
|
-
Sidekiq.dump_json(
|
221
|
-
sidekiq: {
|
222
|
-
processed: sidekiq_stats.processed,
|
223
|
-
failed: sidekiq_stats.failed,
|
224
|
-
busy: sidekiq_stats.workers_size,
|
225
|
-
processes: sidekiq_stats.processes_size,
|
226
|
-
enqueued: sidekiq_stats.enqueued,
|
227
|
-
scheduled: sidekiq_stats.scheduled_size,
|
228
|
-
retries: sidekiq_stats.retry_size,
|
229
|
-
dead: sidekiq_stats.dead_size,
|
230
|
-
default_latency: sidekiq_stats.default_queue_latency
|
231
|
-
},
|
232
|
-
redis: redis_stats
|
233
|
-
)
|
234
|
-
end
|
111
|
+
unless using?(::Rack::Protection) || ENV['RACK_ENV'] == 'test'
|
112
|
+
middlewares.unshift [[::Rack::Protection, { use: :authenticity_token }], nil]
|
113
|
+
end
|
235
114
|
|
236
|
-
|
237
|
-
|
115
|
+
unless using? ::Rack::Session::Cookie
|
116
|
+
unless secret = Web.session_secret
|
117
|
+
require 'securerandom'
|
118
|
+
secret = SecureRandom.hex(64)
|
119
|
+
end
|
238
120
|
|
239
|
-
|
240
|
-
|
241
|
-
queue_stats.lengths
|
242
|
-
)
|
243
|
-
end
|
121
|
+
middlewares.unshift [[::Rack::Session::Cookie, { secret: secret }], nil]
|
122
|
+
end
|
244
123
|
|
245
|
-
|
124
|
+
::Rack::Builder.new do
|
125
|
+
%w(stylesheets javascripts images).each do |asset_dir|
|
126
|
+
map "/#{asset_dir}" do
|
127
|
+
run ::Rack::File.new("#{ASSETS}/#{asset_dir}", { 'Cache-Control' => 'public, max-age=86400' })
|
128
|
+
end
|
129
|
+
end
|
246
130
|
|
247
|
-
|
248
|
-
if params['retry']
|
249
|
-
job.retry
|
250
|
-
elsif params['delete']
|
251
|
-
job.delete
|
252
|
-
elsif params['kill']
|
253
|
-
job.kill
|
254
|
-
end
|
255
|
-
end
|
131
|
+
middlewares.each {|middleware, block| use(*middleware, &block) }
|
256
132
|
|
257
|
-
|
258
|
-
if params['delete']
|
259
|
-
job.delete
|
260
|
-
elsif params['add_to_queue']
|
261
|
-
job.add_to_queue
|
133
|
+
run WebApplication.new(klass)
|
262
134
|
end
|
263
135
|
end
|
264
136
|
end
|
137
|
+
|
138
|
+
Sidekiq::WebApplication.helpers WebHelpers
|
139
|
+
Sidekiq::WebApplication.helpers Sidekiq::Paginator
|
140
|
+
|
141
|
+
Sidekiq::WebAction.class_eval "def _render\n#{ERB.new(File.read(Web::LAYOUT)).src}\nend"
|
265
142
|
end
|
266
143
|
|
267
144
|
if defined?(::ActionDispatch::Request::Session) &&
|
268
145
|
!::ActionDispatch::Request::Session.respond_to?(:each)
|
269
146
|
# mperham/sidekiq#2460
|
270
147
|
# Rack apps can't reuse the Rails session store without
|
271
|
-
# this monkeypatch
|
148
|
+
# this monkeypatch, fixed in Rails 5.
|
272
149
|
class ActionDispatch::Request::Session
|
273
150
|
def each(&block)
|
274
151
|
hash = self.to_hash
|