sidekiq 5.2.9 → 6.2.1
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/Changes.md +232 -0
- data/README.md +18 -34
- data/bin/sidekiq +26 -2
- data/bin/sidekiqload +32 -24
- data/bin/sidekiqmon +8 -0
- data/lib/generators/sidekiq/templates/worker_test.rb.erb +1 -1
- data/lib/generators/sidekiq/worker_generator.rb +21 -13
- data/lib/sidekiq/api.rb +257 -219
- data/lib/sidekiq/cli.rb +144 -180
- data/lib/sidekiq/client.rb +64 -48
- data/lib/sidekiq/delay.rb +5 -6
- data/lib/sidekiq/exception_handler.rb +10 -12
- data/lib/sidekiq/extensions/action_mailer.rb +13 -22
- data/lib/sidekiq/extensions/active_record.rb +13 -10
- data/lib/sidekiq/extensions/class_methods.rb +14 -11
- data/lib/sidekiq/extensions/generic_proxy.rb +4 -4
- data/lib/sidekiq/fetch.rb +38 -31
- data/lib/sidekiq/job_logger.rb +45 -7
- data/lib/sidekiq/job_retry.rb +62 -61
- data/lib/sidekiq/launcher.rb +142 -52
- data/lib/sidekiq/logger.rb +166 -0
- data/lib/sidekiq/manager.rb +11 -13
- data/lib/sidekiq/middleware/chain.rb +15 -5
- data/lib/sidekiq/middleware/i18n.rb +5 -7
- data/lib/sidekiq/monitor.rb +133 -0
- data/lib/sidekiq/paginator.rb +18 -14
- data/lib/sidekiq/processor.rb +71 -70
- data/lib/sidekiq/rails.rb +29 -37
- data/lib/sidekiq/redis_connection.rb +50 -48
- data/lib/sidekiq/scheduled.rb +28 -29
- data/lib/sidekiq/sd_notify.rb +149 -0
- data/lib/sidekiq/systemd.rb +24 -0
- data/lib/sidekiq/testing/inline.rb +2 -1
- data/lib/sidekiq/testing.rb +35 -24
- data/lib/sidekiq/util.rb +45 -16
- data/lib/sidekiq/version.rb +2 -1
- data/lib/sidekiq/web/action.rb +15 -11
- data/lib/sidekiq/web/application.rb +84 -74
- data/lib/sidekiq/web/csrf_protection.rb +180 -0
- data/lib/sidekiq/web/helpers.rb +108 -79
- data/lib/sidekiq/web/router.rb +23 -19
- data/lib/sidekiq/web.rb +60 -105
- data/lib/sidekiq/worker.rb +126 -102
- data/lib/sidekiq.rb +69 -44
- data/sidekiq.gemspec +23 -16
- data/web/assets/images/apple-touch-icon.png +0 -0
- data/web/assets/javascripts/application.js +25 -27
- data/web/assets/javascripts/dashboard.js +4 -23
- data/web/assets/stylesheets/application-dark.css +160 -0
- data/web/assets/stylesheets/application.css +33 -8
- data/web/locales/de.yml +14 -2
- data/web/locales/en.yml +2 -0
- data/web/locales/fr.yml +3 -3
- data/web/locales/ja.yml +4 -1
- data/web/locales/lt.yml +83 -0
- data/web/locales/pl.yml +4 -4
- data/web/locales/ru.yml +4 -0
- data/web/locales/vi.yml +83 -0
- data/web/views/_job_info.erb +2 -1
- data/web/views/busy.erb +51 -17
- data/web/views/dead.erb +2 -2
- data/web/views/layout.erb +2 -0
- data/web/views/morgue.erb +5 -2
- data/web/views/queue.erb +11 -2
- data/web/views/queues.erb +9 -1
- data/web/views/retries.erb +5 -2
- data/web/views/retry.erb +2 -2
- data/web/views/scheduled.erb +5 -2
- metadata +27 -60
- data/.circleci/config.yml +0 -61
- data/.github/contributing.md +0 -32
- data/.github/issue_template.md +0 -11
- data/.gitignore +0 -15
- data/.travis.yml +0 -11
- data/3.0-Upgrade.md +0 -70
- data/4.0-Upgrade.md +0 -53
- data/5.0-Upgrade.md +0 -56
- data/COMM-LICENSE +0 -97
- data/Ent-Changes.md +0 -238
- data/Gemfile +0 -23
- data/Pro-2.0-Upgrade.md +0 -138
- data/Pro-3.0-Upgrade.md +0 -44
- data/Pro-4.0-Upgrade.md +0 -35
- data/Pro-Changes.md +0 -759
- data/Rakefile +0 -9
- data/bin/sidekiqctl +0 -20
- data/code_of_conduct.md +0 -50
- data/lib/sidekiq/core_ext.rb +0 -1
- data/lib/sidekiq/ctl.rb +0 -221
- data/lib/sidekiq/logging.rb +0 -122
- data/lib/sidekiq/middleware/server/active_record.rb +0 -23
data/lib/sidekiq/util.rb
CHANGED
@@ -1,27 +1,54 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
2
|
+
|
3
|
+
require "forwardable"
|
4
|
+
require "socket"
|
5
|
+
require "securerandom"
|
6
|
+
require "sidekiq/exception_handler"
|
5
7
|
|
6
8
|
module Sidekiq
|
7
9
|
##
|
8
10
|
# This module is part of Sidekiq core and not intended for extensions.
|
9
11
|
#
|
12
|
+
|
13
|
+
class RingBuffer
|
14
|
+
include Enumerable
|
15
|
+
extend Forwardable
|
16
|
+
def_delegators :@buf, :[], :each, :size
|
17
|
+
|
18
|
+
def initialize(size, default = 0)
|
19
|
+
@size = size
|
20
|
+
@buf = Array.new(size, default)
|
21
|
+
@index = 0
|
22
|
+
end
|
23
|
+
|
24
|
+
def <<(element)
|
25
|
+
@buf[@index % @size] = element
|
26
|
+
@index += 1
|
27
|
+
element
|
28
|
+
end
|
29
|
+
|
30
|
+
def buffer
|
31
|
+
@buf
|
32
|
+
end
|
33
|
+
|
34
|
+
def reset(default = 0)
|
35
|
+
@buf.fill(default)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
10
39
|
module Util
|
11
40
|
include ExceptionHandler
|
12
41
|
|
13
|
-
EXPIRY = 60 * 60 * 24
|
14
|
-
|
15
42
|
def watchdog(last_words)
|
16
43
|
yield
|
17
44
|
rescue Exception => ex
|
18
|
-
handle_exception(ex, {
|
45
|
+
handle_exception(ex, {context: last_words})
|
19
46
|
raise ex
|
20
47
|
end
|
21
48
|
|
22
49
|
def safe_thread(name, &block)
|
23
50
|
Thread.new do
|
24
|
-
Thread.current
|
51
|
+
Thread.current.name = name
|
25
52
|
watchdog(name, &block)
|
26
53
|
end
|
27
54
|
end
|
@@ -34,8 +61,12 @@ module Sidekiq
|
|
34
61
|
Sidekiq.redis(&block)
|
35
62
|
end
|
36
63
|
|
64
|
+
def tid
|
65
|
+
Thread.current["sidekiq_tid"] ||= (Thread.current.object_id ^ ::Process.pid).to_s(36)
|
66
|
+
end
|
67
|
+
|
37
68
|
def hostname
|
38
|
-
ENV[
|
69
|
+
ENV["DYNO"] || Socket.gethostname
|
39
70
|
end
|
40
71
|
|
41
72
|
def process_nonce
|
@@ -43,22 +74,20 @@ module Sidekiq
|
|
43
74
|
end
|
44
75
|
|
45
76
|
def identity
|
46
|
-
@@identity ||= "#{hostname}:#{
|
77
|
+
@@identity ||= "#{hostname}:#{::Process.pid}:#{process_nonce}"
|
47
78
|
end
|
48
79
|
|
49
|
-
def fire_event(event, options={})
|
80
|
+
def fire_event(event, options = {})
|
50
81
|
reverse = options[:reverse]
|
51
82
|
reraise = options[:reraise]
|
52
83
|
|
53
84
|
arr = Sidekiq.options[:lifecycle_events][event]
|
54
85
|
arr.reverse! if reverse
|
55
86
|
arr.each do |block|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
raise ex if reraise
|
61
|
-
end
|
87
|
+
block.call
|
88
|
+
rescue => ex
|
89
|
+
handle_exception(ex, {context: "Exception during Sidekiq lifecycle event.", event: event})
|
90
|
+
raise ex if reraise
|
62
91
|
end
|
63
92
|
arr.clear
|
64
93
|
end
|
data/lib/sidekiq/version.rb
CHANGED
data/lib/sidekiq/web/action.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Sidekiq
|
4
4
|
class WebAction
|
5
|
-
RACK_SESSION =
|
5
|
+
RACK_SESSION = "rack.session"
|
6
6
|
|
7
7
|
attr_accessor :env, :block, :type
|
8
8
|
|
@@ -15,18 +15,18 @@ module Sidekiq
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def halt(res)
|
18
|
-
throw :halt, res
|
18
|
+
throw :halt, [res, {"Content-Type" => "text/plain"}, [res.to_s]]
|
19
19
|
end
|
20
20
|
|
21
21
|
def redirect(location)
|
22
|
-
throw :halt, [302, {
|
22
|
+
throw :halt, [302, {"Location" => "#{request.base_url}#{location}"}, []]
|
23
23
|
end
|
24
24
|
|
25
25
|
def params
|
26
|
-
indifferent_hash = Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
|
26
|
+
indifferent_hash = Hash.new { |hash, key| hash[key.to_s] if Symbol === key }
|
27
27
|
|
28
28
|
indifferent_hash.merge! request.params
|
29
|
-
route_params.each {|k,v| indifferent_hash[k.to_s] = v }
|
29
|
+
route_params.each { |k, v| indifferent_hash[k.to_s] = v }
|
30
30
|
|
31
31
|
indifferent_hash
|
32
32
|
end
|
@@ -40,10 +40,14 @@ module Sidekiq
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def erb(content, options = {})
|
43
|
-
if content.
|
43
|
+
if content.is_a? Symbol
|
44
44
|
unless respond_to?(:"_erb_#{content}")
|
45
45
|
src = ERB.new(File.read("#{Web.settings.views}/#{content}.erb")).src
|
46
|
-
WebAction.class_eval
|
46
|
+
WebAction.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
47
|
+
def _erb_#{content}
|
48
|
+
#{src}
|
49
|
+
end
|
50
|
+
RUBY
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
@@ -64,22 +68,22 @@ module Sidekiq
|
|
64
68
|
end
|
65
69
|
|
66
70
|
def json(payload)
|
67
|
-
[200, {
|
71
|
+
[200, {"Content-Type" => "application/json", "Cache-Control" => "no-cache"}, [Sidekiq.dump_json(payload)]]
|
68
72
|
end
|
69
73
|
|
70
74
|
def initialize(env, block)
|
71
75
|
@_erb = false
|
72
76
|
@env = env
|
73
77
|
@block = block
|
74
|
-
|
78
|
+
@files ||= {}
|
75
79
|
end
|
76
80
|
|
77
81
|
private
|
78
82
|
|
79
83
|
def _erb(file, locals)
|
80
|
-
locals
|
84
|
+
locals&.each { |k, v| define_singleton_method(k) { v } unless singleton_methods.include? k }
|
81
85
|
|
82
|
-
if file.
|
86
|
+
if file.is_a?(String)
|
83
87
|
ERB.new(file).result(binding)
|
84
88
|
else
|
85
89
|
send(:"_erb_#{file}")
|
@@ -4,9 +4,7 @@ module Sidekiq
|
|
4
4
|
class WebApplication
|
5
5
|
extend WebRouter
|
6
6
|
|
7
|
-
|
8
|
-
CONTENT_TYPE = "Content-Type"
|
9
|
-
REDIS_KEYS = %w(redis_version uptime_in_days connected_clients used_memory_human used_memory_peak_human)
|
7
|
+
REDIS_KEYS = %w[redis_version uptime_in_days connected_clients used_memory_human used_memory_peak_human]
|
10
8
|
CSP_HEADER = [
|
11
9
|
"default-src 'self' https: http:",
|
12
10
|
"child-src 'self'",
|
@@ -21,7 +19,7 @@ module Sidekiq
|
|
21
19
|
"style-src 'self' https: http: 'unsafe-inline'",
|
22
20
|
"worker-src 'self'",
|
23
21
|
"base-uri 'self'"
|
24
|
-
].join(
|
22
|
+
].join("; ").freeze
|
25
23
|
|
26
24
|
def initialize(klass)
|
27
25
|
@klass = klass
|
@@ -43,9 +41,16 @@ module Sidekiq
|
|
43
41
|
# nothing, backwards compatibility
|
44
42
|
end
|
45
43
|
|
44
|
+
head "/" do
|
45
|
+
# HEAD / is the cheapest heartbeat possible,
|
46
|
+
# it hits Redis to ensure connectivity
|
47
|
+
Sidekiq.redis { |c| c.llen("queue:default") }
|
48
|
+
""
|
49
|
+
end
|
50
|
+
|
46
51
|
get "/" do
|
47
|
-
@redis_info = redis_info.select{ |k, v| REDIS_KEYS.include? k }
|
48
|
-
stats_history = Sidekiq::Stats::History.new((params[
|
52
|
+
@redis_info = redis_info.select { |k, v| REDIS_KEYS.include? k }
|
53
|
+
stats_history = Sidekiq::Stats::History.new((params["days"] || 30).to_i)
|
49
54
|
@processed_history = stats_history.processed
|
50
55
|
@failed_history = stats_history.failed
|
51
56
|
|
@@ -57,14 +62,14 @@ module Sidekiq
|
|
57
62
|
end
|
58
63
|
|
59
64
|
post "/busy" do
|
60
|
-
if params[
|
61
|
-
p = Sidekiq::Process.new(
|
62
|
-
p.quiet! if params[
|
63
|
-
p.stop! if params[
|
65
|
+
if params["identity"]
|
66
|
+
p = Sidekiq::Process.new("identity" => params["identity"])
|
67
|
+
p.quiet! if params["quiet"]
|
68
|
+
p.stop! if params["stop"]
|
64
69
|
else
|
65
70
|
processes.each do |pro|
|
66
|
-
pro.quiet! if params[
|
67
|
-
pro.stop! if params[
|
71
|
+
pro.quiet! if params["quiet"]
|
72
|
+
pro.stop! if params["stop"]
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
@@ -77,42 +82,53 @@ module Sidekiq
|
|
77
82
|
erb(:queues)
|
78
83
|
end
|
79
84
|
|
85
|
+
QUEUE_NAME = /\A[a-z_:.\-0-9]+\z/i
|
86
|
+
|
80
87
|
get "/queues/:name" do
|
81
88
|
@name = route_params[:name]
|
82
89
|
|
83
|
-
halt(404)
|
90
|
+
halt(404) if !@name || @name !~ QUEUE_NAME
|
84
91
|
|
85
|
-
@count = (params[
|
92
|
+
@count = (params["count"] || 25).to_i
|
86
93
|
@queue = Sidekiq::Queue.new(@name)
|
87
|
-
(@current_page, @total_size, @messages) = page("queue:#{@name}", params[
|
94
|
+
(@current_page, @total_size, @messages) = page("queue:#{@name}", params["page"], @count, reverse: params["direction"] == "asc")
|
88
95
|
@messages = @messages.map { |msg| Sidekiq::Job.new(msg, @name) }
|
89
96
|
|
90
97
|
erb(:queue)
|
91
98
|
end
|
92
99
|
|
93
100
|
post "/queues/:name" do
|
94
|
-
Sidekiq::Queue.new(route_params[:name])
|
101
|
+
queue = Sidekiq::Queue.new(route_params[:name])
|
102
|
+
|
103
|
+
if Sidekiq.pro? && params["pause"]
|
104
|
+
queue.pause!
|
105
|
+
elsif Sidekiq.pro? && params["unpause"]
|
106
|
+
queue.unpause!
|
107
|
+
else
|
108
|
+
queue.clear
|
109
|
+
end
|
95
110
|
|
96
111
|
redirect "#{root_path}queues"
|
97
112
|
end
|
98
113
|
|
99
114
|
post "/queues/:name/delete" do
|
100
115
|
name = route_params[:name]
|
101
|
-
Sidekiq::Job.new(params[
|
116
|
+
Sidekiq::Job.new(params["key_val"], name).delete
|
102
117
|
|
103
118
|
redirect_with_query("#{root_path}queues/#{CGI.escape(name)}")
|
104
119
|
end
|
105
120
|
|
106
|
-
get
|
107
|
-
@count = (params[
|
108
|
-
(@current_page, @total_size, @dead) = page("dead", params[
|
121
|
+
get "/morgue" do
|
122
|
+
@count = (params["count"] || 25).to_i
|
123
|
+
(@current_page, @total_size, @dead) = page("dead", params["page"], @count, reverse: true)
|
109
124
|
@dead = @dead.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
110
125
|
|
111
126
|
erb(:morgue)
|
112
127
|
end
|
113
128
|
|
114
129
|
get "/morgue/:key" do
|
115
|
-
|
130
|
+
key = route_params[:key]
|
131
|
+
halt(404) unless key
|
116
132
|
|
117
133
|
@dead = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
|
118
134
|
|
@@ -123,10 +139,10 @@ module Sidekiq
|
|
123
139
|
end
|
124
140
|
end
|
125
141
|
|
126
|
-
post
|
127
|
-
redirect(request.path) unless params[
|
142
|
+
post "/morgue" do
|
143
|
+
redirect(request.path) unless params["key"]
|
128
144
|
|
129
|
-
params[
|
145
|
+
params["key"].each do |key|
|
130
146
|
job = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
|
131
147
|
retry_or_delete_or_kill job, params if job
|
132
148
|
end
|
@@ -147,7 +163,8 @@ module Sidekiq
|
|
147
163
|
end
|
148
164
|
|
149
165
|
post "/morgue/:key" do
|
150
|
-
|
166
|
+
key = route_params[:key]
|
167
|
+
halt(404) unless key
|
151
168
|
|
152
169
|
job = Sidekiq::DeadSet.new.fetch(*parse_params(key)).first
|
153
170
|
retry_or_delete_or_kill job, params if job
|
@@ -155,9 +172,9 @@ module Sidekiq
|
|
155
172
|
redirect_with_query("#{root_path}morgue")
|
156
173
|
end
|
157
174
|
|
158
|
-
get
|
159
|
-
@count = (params[
|
160
|
-
(@current_page, @total_size, @retries) = page("retry", params[
|
175
|
+
get "/retries" do
|
176
|
+
@count = (params["count"] || 25).to_i
|
177
|
+
(@current_page, @total_size, @retries) = page("retry", params["page"], @count)
|
161
178
|
@retries = @retries.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
162
179
|
|
163
180
|
erb(:retries)
|
@@ -173,10 +190,10 @@ module Sidekiq
|
|
173
190
|
end
|
174
191
|
end
|
175
192
|
|
176
|
-
post
|
177
|
-
redirect(request.path) unless params[
|
193
|
+
post "/retries" do
|
194
|
+
redirect(request.path) unless params["key"]
|
178
195
|
|
179
|
-
params[
|
196
|
+
params["key"].each do |key|
|
180
197
|
job = Sidekiq::RetrySet.new.fetch(*parse_params(key)).first
|
181
198
|
retry_or_delete_or_kill job, params if job
|
182
199
|
end
|
@@ -210,9 +227,9 @@ module Sidekiq
|
|
210
227
|
redirect_with_query("#{root_path}retries")
|
211
228
|
end
|
212
229
|
|
213
|
-
get
|
214
|
-
@count = (params[
|
215
|
-
(@current_page, @total_size, @scheduled) = page("schedule", params[
|
230
|
+
get "/scheduled" do
|
231
|
+
@count = (params["count"] || 25).to_i
|
232
|
+
(@current_page, @total_size, @scheduled) = page("schedule", params["page"], @count)
|
216
233
|
@scheduled = @scheduled.map { |msg, score| Sidekiq::SortedEntry.new(nil, score, msg) }
|
217
234
|
|
218
235
|
erb(:scheduled)
|
@@ -228,10 +245,10 @@ module Sidekiq
|
|
228
245
|
end
|
229
246
|
end
|
230
247
|
|
231
|
-
post
|
232
|
-
redirect(request.path) unless params[
|
248
|
+
post "/scheduled" do
|
249
|
+
redirect(request.path) unless params["key"]
|
233
250
|
|
234
|
-
params[
|
251
|
+
params["key"].each do |key|
|
235
252
|
job = Sidekiq::ScheduledSet.new.fetch(*parse_params(key)).first
|
236
253
|
delete_or_add_queue job, params if job
|
237
254
|
end
|
@@ -240,7 +257,8 @@ module Sidekiq
|
|
240
257
|
end
|
241
258
|
|
242
259
|
post "/scheduled/:key" do
|
243
|
-
|
260
|
+
key = route_params[:key]
|
261
|
+
halt(404) unless key
|
244
262
|
|
245
263
|
job = Sidekiq::ScheduledSet.new.fetch(*parse_params(key)).first
|
246
264
|
delete_or_add_queue job, params if job
|
@@ -248,23 +266,23 @@ module Sidekiq
|
|
248
266
|
redirect_with_query("#{root_path}scheduled")
|
249
267
|
end
|
250
268
|
|
251
|
-
get
|
269
|
+
get "/dashboard/stats" do
|
252
270
|
redirect "#{root_path}stats"
|
253
271
|
end
|
254
272
|
|
255
|
-
get
|
273
|
+
get "/stats" do
|
256
274
|
sidekiq_stats = Sidekiq::Stats.new
|
257
|
-
redis_stats
|
275
|
+
redis_stats = redis_info.select { |k, v| REDIS_KEYS.include? k }
|
258
276
|
json(
|
259
277
|
sidekiq: {
|
260
|
-
processed:
|
261
|
-
failed:
|
262
|
-
busy:
|
263
|
-
processes:
|
264
|
-
enqueued:
|
265
|
-
scheduled:
|
266
|
-
retries:
|
267
|
-
dead:
|
278
|
+
processed: sidekiq_stats.processed,
|
279
|
+
failed: sidekiq_stats.failed,
|
280
|
+
busy: sidekiq_stats.workers_size,
|
281
|
+
processes: sidekiq_stats.processes_size,
|
282
|
+
enqueued: sidekiq_stats.enqueued,
|
283
|
+
scheduled: sidekiq_stats.scheduled_size,
|
284
|
+
retries: sidekiq_stats.retry_size,
|
285
|
+
dead: sidekiq_stats.dead_size,
|
268
286
|
default_latency: sidekiq_stats.default_queue_latency
|
269
287
|
},
|
270
288
|
redis: redis_stats,
|
@@ -272,60 +290,52 @@ module Sidekiq
|
|
272
290
|
)
|
273
291
|
end
|
274
292
|
|
275
|
-
get
|
293
|
+
get "/stats/queues" do
|
276
294
|
json Sidekiq::Stats::Queues.new.lengths
|
277
295
|
end
|
278
296
|
|
279
297
|
def call(env)
|
280
298
|
action = self.class.match(env)
|
281
|
-
return [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"
|
299
|
+
return [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found"]] unless action
|
282
300
|
|
283
|
-
|
284
|
-
|
301
|
+
app = @klass
|
302
|
+
resp = catch(:halt) do # rubocop:disable Standard/SemanticBlocks
|
285
303
|
self.class.run_befores(app, action)
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
self.class.run_afters(app, action)
|
290
|
-
end
|
291
|
-
|
292
|
-
resp
|
304
|
+
action.instance_exec env, &action.block
|
305
|
+
ensure
|
306
|
+
self.class.run_afters(app, action)
|
293
307
|
end
|
294
308
|
|
295
|
-
|
309
|
+
case resp
|
296
310
|
when Array
|
311
|
+
# redirects go here
|
297
312
|
resp
|
298
313
|
else
|
314
|
+
# rendered content goes here
|
299
315
|
headers = {
|
300
316
|
"Content-Type" => "text/html",
|
301
317
|
"Cache-Control" => "no-cache",
|
302
318
|
"Content-Language" => action.locale,
|
303
319
|
"Content-Security-Policy" => CSP_HEADER
|
304
320
|
}
|
305
|
-
|
321
|
+
# we'll let Rack calculate Content-Length for us.
|
306
322
|
[200, headers, [resp]]
|
307
323
|
end
|
308
|
-
|
309
|
-
resp[1] = resp[1].dup
|
310
|
-
|
311
|
-
resp[1][CONTENT_LENGTH] = resp[2].inject(0) { |l, p| l + p.bytesize }.to_s
|
312
|
-
|
313
|
-
resp
|
314
324
|
end
|
315
325
|
|
316
|
-
def self.helpers(mod=nil, &block)
|
317
|
-
if
|
326
|
+
def self.helpers(mod = nil, &block)
|
327
|
+
if block
|
318
328
|
WebAction.class_eval(&block)
|
319
329
|
else
|
320
330
|
WebAction.send(:include, mod)
|
321
331
|
end
|
322
332
|
end
|
323
333
|
|
324
|
-
def self.before(path=nil, &block)
|
334
|
+
def self.before(path = nil, &block)
|
325
335
|
befores << [path && Regexp.new("\\A#{path.gsub("*", ".*")}\\z"), block]
|
326
336
|
end
|
327
337
|
|
328
|
-
def self.after(path=nil, &block)
|
338
|
+
def self.after(path = nil, &block)
|
329
339
|
afters << [path && Regexp.new("\\A#{path.gsub("*", ".*")}\\z"), block]
|
330
340
|
end
|
331
341
|
|
@@ -338,8 +348,8 @@ module Sidekiq
|
|
338
348
|
end
|
339
349
|
|
340
350
|
def self.run_hooks(hooks, app, action)
|
341
|
-
hooks.select { |p,_| !p || p =~ action.env[WebRouter::PATH_INFO] }
|
342
|
-
|
351
|
+
hooks.select { |p, _| !p || p =~ action.env[WebRouter::PATH_INFO] }
|
352
|
+
.each { |_, b| action.instance_exec(action.env, app, &b) }
|
343
353
|
end
|
344
354
|
|
345
355
|
def self.befores
|