resque 2.7.0 → 3.0.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 +4 -4
- data/HISTORY.md +47 -0
- data/README.markdown +22 -21
- data/Rakefile +27 -1
- data/lib/active_job/queue_adapters/resque_adapter.rb +54 -0
- data/lib/resque/failure/redis.rb +1 -1
- data/lib/resque/helpers.rb +13 -8
- data/lib/resque/railtie.rb +6 -0
- data/lib/resque/server/views/failed.erb +2 -2
- data/lib/resque/server/views/failed_job.erb +7 -7
- data/lib/resque/server/views/failed_queues_overview.erb +3 -3
- data/lib/resque/server/views/job_class.erb +2 -2
- data/lib/resque/server/views/key_sets.erb +2 -2
- data/lib/resque/server/views/key_string.erb +1 -1
- data/lib/resque/server/views/layout.erb +3 -3
- data/lib/resque/server/views/next_more.erb +3 -3
- data/lib/resque/server/views/processing.erb +1 -1
- data/lib/resque/server/views/queues.erb +4 -4
- data/lib/resque/server/views/stats.erb +5 -5
- data/lib/resque/server/views/workers.erb +11 -11
- data/lib/resque/server/views/working.erb +8 -8
- data/lib/resque/server.rb +1 -1
- data/lib/resque/server_helper.rb +2 -2
- data/lib/resque/tasks.rb +5 -1
- data/lib/resque/version.rb +1 -1
- data/lib/resque/web_runner.rb +17 -7
- data/lib/resque/worker.rb +32 -5
- data/lib/resque.rb +31 -6
- metadata +50 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 357503e977394f513419b3146484eab796354a978d6d96e74e16fae0dc2fd3de
|
|
4
|
+
data.tar.gz: 4e3da6258793f0b094cba61c35436d30f1193d8d43553e312b8e5c14cbb7ee5b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 00e3f45822df5638bb129c32c10878e2651cb74081711d4d4ef30da47403195c07276a4dbcb60e650c35dbc40ba0bcfb48d4a2c625eb442dec476e8a18929a7a
|
|
7
|
+
data.tar.gz: 942ff614b651c87ab52726aa88564243fd60b3c87edff7670fcb61491f2a45516a8c91eed44119d5945a322f0598f9be28d3ab5d610146e9d488e261514bf0af
|
data/HISTORY.md
CHANGED
|
@@ -1,3 +1,50 @@
|
|
|
1
|
+
## 3.0.2
|
|
2
|
+
|
|
3
|
+
### Added
|
|
4
|
+
|
|
5
|
+
* resque-web: Support IPv6 hosts in the server URL (#1938)
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
* resque-web: Escape queue names, worker IDs, job classes, failed job details, Redis keys/values, and the reflected request path; serve `/stats.txt` as `text/plain` (#1946)
|
|
10
|
+
* resque-web: Fix the class filter link URL on the failed jobs page (#1934)
|
|
11
|
+
* Prefer `MultiJson.generate`/`parse` over the deprecated `dump`/`load` (#1944)
|
|
12
|
+
* Add tests covering which hooks run in which process (#1932)
|
|
13
|
+
|
|
14
|
+
## 3.0.1
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
* resque-web: Fix reflected XSS in the key sets endpoint (#1942)
|
|
19
|
+
* Address multi_json class name deprecation warning (#1940)
|
|
20
|
+
* Update the Rails initializer docs to load Redis config with `config_for` (#1936)
|
|
21
|
+
* Add tests covering queue priority ordering with wildcards (#1930)
|
|
22
|
+
|
|
23
|
+
## 3.0.0
|
|
24
|
+
|
|
25
|
+
### Breaking Changes
|
|
26
|
+
|
|
27
|
+
* **Minimum Ruby version is now 3.0.0** - Ruby 2.x is no longer supported
|
|
28
|
+
* **Minimum Sinatra version is now 2.0** - old Sinatra versions (0.9-1.x) are no longer supported
|
|
29
|
+
* **Rack 1.x is no longer supported** - Resque now requires Rack 2.x or greater
|
|
30
|
+
* **Minimum Rails version is now 7.2** - You can use Resque without Rails, but if you use it with Rails it must be a version that is still supported
|
|
31
|
+
|
|
32
|
+
### Added
|
|
33
|
+
|
|
34
|
+
* Rack 3 support and switched default Rack handler to Puma (#1912)
|
|
35
|
+
* Ruby 3.4 and Rails 8.1 support (#1912 and #1906)
|
|
36
|
+
* Upstream Active Job adapter from Rails (#1906)
|
|
37
|
+
* Explicit `redis` (>= 4.0) and `base64` (~> 0.1) gem dependencies (#1922)
|
|
38
|
+
* Added `shutdown` hooks - allows plugins and adapters to know when a worker is shutting down, enabling features like Active Job Continuations (#1916, #1924)
|
|
39
|
+
* Added support for dynamic interval sleep - workers can now use a faster polling interval that automatically backs off when idle, reducing Redis load (#1920)
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
* Fix circular require from Rails ActiveJob adapter (#1906)
|
|
44
|
+
* Fix failed job `retried_at` timezone data (#1918)
|
|
45
|
+
* Fix double Redis get when checking for paused workers (#1919)
|
|
46
|
+
* Documentation cleanup (#1903, #1917)
|
|
47
|
+
|
|
1
48
|
## 2.7.0
|
|
2
49
|
|
|
3
50
|
### Fixed
|
data/README.markdown
CHANGED
|
@@ -39,15 +39,23 @@ The Resque frontend tells you what workers are doing, what workers are
|
|
|
39
39
|
not doing, what queues you're using, what's in those queues, provides
|
|
40
40
|
general usage stats, and helps you track failures.
|
|
41
41
|
|
|
42
|
-
Resque
|
|
43
|
-
We will also only be supporting Redis 3.0 and above going forward.
|
|
42
|
+
Resque 3.0 requires Ruby 3.0.0 or newer.
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
**Version Support:**
|
|
45
|
+
- Ruby: 3.0, 3.1, 3.2, 3.3, 3.4+
|
|
46
|
+
- Redis gem: 4.0+
|
|
47
|
+
- Rack: 2.x or 3.x
|
|
48
|
+
- Rails (for ActiveJob): 7.2+ (requires Ruby 3.1+ for Rails 8.0+)
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
### Resque 3.0
|
|
51
|
+
|
|
52
|
+
Resque 3.0 is a major release that modernizes the codebase with updated dependency requirements:
|
|
53
|
+
- Requires Ruby 3.0+ (drops support for Ruby 2.x)
|
|
54
|
+
- Requires redis gem 4.0+ (tested with redis gem 4.x and 5.x)
|
|
55
|
+
- Requires Sinatra 2.0+ (with Rack 2.x or 3.x support via appropriate Sinatra version)
|
|
56
|
+
- Maintains compatibility with Rails 7.2+ and ActiveJob
|
|
57
|
+
|
|
58
|
+
If you need Ruby 2.x support, please use Resque 2.x.
|
|
51
59
|
|
|
52
60
|
Example
|
|
53
61
|
-------
|
|
@@ -133,15 +141,6 @@ require 'your/app' # Include this line if you want your workers to have access t
|
|
|
133
141
|
|
|
134
142
|
#### Rails
|
|
135
143
|
|
|
136
|
-
##### Rails 7.1
|
|
137
|
-
|
|
138
|
-
If you're using Rails 7.1.x, use [rack-session version 1.0.2](https://rubygems.org/gems/rack-session/versions/1.0.2). This is because resque-web's dependency, [Sinatra, isn't compatible with rack 3.0](https://github.com/sinatra/sinatra/issues/1797), which is [required by rack-session 2.0.0](https://rubygems.org/gems/rack-session/versions/2.0.0).
|
|
139
|
-
|
|
140
|
-
```
|
|
141
|
-
gem 'rails', '~> 7.1'
|
|
142
|
-
gem 'rack-session', '~> 1.0', '>= 1.0.2'
|
|
143
|
-
```
|
|
144
|
-
|
|
145
144
|
To make resque specific changes, you can override the `resque:setup` job in `lib/tasks` (ex: `lib/tasks/resque.rake`). GitHub's setup task looks like this:
|
|
146
145
|
|
|
147
146
|
``` ruby
|
|
@@ -496,12 +495,14 @@ Here's our `config/resque.yml`:
|
|
|
496
495
|
And our initializer:
|
|
497
496
|
|
|
498
497
|
``` ruby
|
|
499
|
-
|
|
500
|
-
rails_env = ENV['RAILS_ENV'] ||
|
|
501
|
-
config_file = rails_root + '/config/resque.yml'
|
|
498
|
+
config_file = 'config/resque.yml'
|
|
499
|
+
rails_env = ENV['RAILS_ENV'] || Rails.env
|
|
502
500
|
|
|
503
|
-
resque_config = YAML::
|
|
501
|
+
resque_config = YAML::load_file(config_file)
|
|
504
502
|
Resque.redis = resque_config[rails_env]
|
|
503
|
+
|
|
504
|
+
# OR auto load with current env
|
|
505
|
+
Resque.redis = Rails.application.config_for(:resque)
|
|
505
506
|
```
|
|
506
507
|
|
|
507
508
|
Easy peasy! Why not just use `RAILS_ROOT` and `RAILS_ENV`? Because
|
|
@@ -633,7 +634,7 @@ Choose DelayedJob if:
|
|
|
633
634
|
* You like numeric priorities
|
|
634
635
|
* You're not doing a gigantic amount of jobs each day
|
|
635
636
|
* Your queue stays small and nimble
|
|
636
|
-
* There is not a lot failure / chaos
|
|
637
|
+
* There is not a lot of failure / chaos
|
|
637
638
|
* You want to easily throw anything on the queue
|
|
638
639
|
* You don't want to setup Redis
|
|
639
640
|
|
data/Rakefile
CHANGED
|
@@ -28,7 +28,33 @@ Rake::TestTask.new do |test|
|
|
|
28
28
|
test.verbose = true
|
|
29
29
|
test.libs << "test"
|
|
30
30
|
test.libs << "lib"
|
|
31
|
-
test.test_files = FileList['test/**/*_test.rb']
|
|
31
|
+
test.test_files = FileList['test/**/*_test.rb'].exclude('test/active_job/**/*')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
Rake::TestTask.new('test:activejob') do |test|
|
|
35
|
+
test.verbose = true
|
|
36
|
+
test.libs << "test"
|
|
37
|
+
test.libs << "lib"
|
|
38
|
+
test.libs << "test/active_job"
|
|
39
|
+
test.test_files = FileList['test/active_job/cases/*_test.rb']
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
task "env:aj_integration" do
|
|
43
|
+
ENV["AJ_INTEGRATION_TESTS"] = "1"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Rake::TestTask.new('test:activejob:integration' => 'env:aj_integration') do |t|
|
|
47
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.1")
|
|
48
|
+
puts "Integration tests require Ruby 3.1 or later"
|
|
49
|
+
exit 0
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
t.description = "Run integration tests for Resque::ActiveJob::Adapter"
|
|
53
|
+
t.libs << "test"
|
|
54
|
+
t.libs << "test/active_job"
|
|
55
|
+
t.test_files = FileList["test/active_job/integration/**/*_test.rb"]
|
|
56
|
+
t.verbose = true
|
|
57
|
+
t.warning = true
|
|
32
58
|
end
|
|
33
59
|
|
|
34
60
|
if command? :kicker
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/enumerable"
|
|
4
|
+
require "active_support/core_ext/array/access"
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
require "resque-scheduler"
|
|
8
|
+
rescue LoadError
|
|
9
|
+
begin
|
|
10
|
+
require "resque_scheduler"
|
|
11
|
+
rescue LoadError
|
|
12
|
+
false
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module ActiveJob
|
|
17
|
+
module QueueAdapters
|
|
18
|
+
remove_const(:ResqueAdapter) if defined?(ResqueAdapter)
|
|
19
|
+
|
|
20
|
+
# = Resque adapter for Active Job
|
|
21
|
+
#
|
|
22
|
+
# Resque (pronounced like "rescue") is a Redis-backed library for creating
|
|
23
|
+
# background jobs, placing those jobs on multiple queues, and processing
|
|
24
|
+
# them later.
|
|
25
|
+
#
|
|
26
|
+
# Read more about Resque {here}[https://github.com/resque/resque].
|
|
27
|
+
#
|
|
28
|
+
# To use Resque set the queue_adapter config to +:resque+.
|
|
29
|
+
#
|
|
30
|
+
# Rails.application.config.active_job.queue_adapter = :resque
|
|
31
|
+
class ResqueAdapter < ::ActiveJob::QueueAdapters::AbstractAdapter
|
|
32
|
+
def enqueue(job) # :nodoc:
|
|
33
|
+
JobWrapper.instance_variable_set(:@queue, job.queue_name)
|
|
34
|
+
Resque.enqueue_to job.queue_name, JobWrapper, job.serialize
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def enqueue_at(job, timestamp) # :nodoc:
|
|
38
|
+
unless Resque.respond_to?(:enqueue_at_with_queue)
|
|
39
|
+
raise NotImplementedError, "To be able to schedule jobs with Resque you need the " \
|
|
40
|
+
"resque-scheduler gem. Please add it to your Gemfile and run bundle install"
|
|
41
|
+
end
|
|
42
|
+
Resque.enqueue_at_with_queue job.queue_name, timestamp, JobWrapper, job.serialize
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
class JobWrapper # :nodoc:
|
|
46
|
+
class << self
|
|
47
|
+
def perform(job_data)
|
|
48
|
+
::ActiveJob::Base.execute job_data
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
data/lib/resque/failure/redis.rb
CHANGED
|
@@ -78,7 +78,7 @@ module Resque
|
|
|
78
78
|
def self.requeue(id, queue = nil)
|
|
79
79
|
check_queue(queue)
|
|
80
80
|
item = all(id)
|
|
81
|
-
item['retried_at'] = Time.now.strftime("%Y/%m/%d %H:%M:%S")
|
|
81
|
+
item['retried_at'] = UTF8Util.clean(Time.now.strftime("%Y/%m/%d %H:%M:%S %Z"))
|
|
82
82
|
data_store.update_item_in_failed_queue(id,Resque.encode(item))
|
|
83
83
|
Job.create(item['queue'], item['payload']['class'], *item['payload']['args'])
|
|
84
84
|
end
|
data/lib/resque/helpers.rb
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
require 'multi_json'
|
|
2
2
|
|
|
3
|
-
# OkJson won't work because it doesn't serialize symbols
|
|
4
|
-
# in the same way yajl and json do.
|
|
5
|
-
if MultiJson.respond_to?(:adapter)
|
|
6
|
-
raise "Please install the yajl-ruby or json gem" if MultiJson.adapter.to_s == 'MultiJson::Adapters::OkJson'
|
|
7
|
-
elsif MultiJson.respond_to?(:engine)
|
|
8
|
-
raise "Please install the yajl-ruby or json gem" if MultiJson.engine.to_s == 'MultiJson::Engines::OkJson'
|
|
9
|
-
end
|
|
10
|
-
|
|
11
3
|
module Resque
|
|
4
|
+
# multi_json renamed it's top-level constant from MultiJson to MultiJSON,
|
|
5
|
+
# keeping MultiJson as a deprecated alias until v2.0. Reference whichever name the
|
|
6
|
+
# installed version exposes so we stay compatible with future versions of multi_json
|
|
7
|
+
MultiJson = defined?(::MultiJSON) ? ::MultiJSON : ::MultiJson
|
|
8
|
+
|
|
9
|
+
# OkJson won't work because it doesn't serialize symbols
|
|
10
|
+
# in the same way yajl and json do.
|
|
11
|
+
if MultiJson.respond_to?(:adapter)
|
|
12
|
+
raise "Please install the yajl-ruby or json gem" if MultiJson.adapter.to_s.end_with?('::OkJson')
|
|
13
|
+
elsif MultiJson.respond_to?(:engine)
|
|
14
|
+
raise "Please install the yajl-ruby or json gem" if MultiJson.engine.to_s.end_with?('::OkJson')
|
|
15
|
+
end
|
|
16
|
+
|
|
12
17
|
# Methods used by various classes in Resque.
|
|
13
18
|
module Helpers
|
|
14
19
|
class DecodeException < StandardError; end
|
data/lib/resque/railtie.rb
CHANGED
|
@@ -6,5 +6,11 @@ module Resque
|
|
|
6
6
|
# redefine ths task to load the rails env
|
|
7
7
|
task "resque:setup" => :environment
|
|
8
8
|
end
|
|
9
|
+
|
|
10
|
+
initializer "resque.active_job" do
|
|
11
|
+
ActiveSupport.on_load(:active_job) do
|
|
12
|
+
require "active_job/queue_adapters/resque_adapter"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
9
15
|
end
|
|
10
16
|
end
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<% end %>
|
|
6
6
|
|
|
7
7
|
<% unless failed_size.zero? %>
|
|
8
|
-
<form method="POST" action="<%= u
|
|
8
|
+
<form method="POST" action="<%= h u("failed#{'/' + params[:queue] if params[:queue]}/clear") %>">
|
|
9
9
|
<input type="submit" name="" value="Clear <%= params[:queue] ? "'#{escape_html(params[:queue])}'" : 'Failed' %> Jobs" class="confirmSubmission" />
|
|
10
10
|
</form>
|
|
11
11
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
<input type="submit" name="" value="Clear Retried Jobs" onclick='return confirm("Are you absolutely sure? This cannot be undone.");' />
|
|
15
15
|
</form>
|
|
16
16
|
<% end %>
|
|
17
|
-
<form method="POST" action="<%= u
|
|
17
|
+
<form method="POST" action="<%= h u("failed#{'/' + params[:queue] if params[:queue]}/requeue/all") %>">
|
|
18
18
|
<input type="submit" name="" value="Retry <%= params[:queue] ? "'#{escape_html(params[:queue])}'" : 'Failed' %> Jobs" class="confirmSubmission" />
|
|
19
19
|
</form>
|
|
20
20
|
<% end %>
|
|
@@ -2,28 +2,28 @@
|
|
|
2
2
|
<dl>
|
|
3
3
|
<% if job.nil? %>
|
|
4
4
|
<dt>Error</dt>
|
|
5
|
-
<dd>Job <%= id %> could not be parsed; perhaps it contains invalid JSON?</dd>
|
|
5
|
+
<dd>Job <%= h id %> could not be parsed; perhaps it contains invalid JSON?</dd>
|
|
6
6
|
<% else %>
|
|
7
7
|
<dt>Worker</dt>
|
|
8
8
|
<dd>
|
|
9
|
-
<a href="<%= u(:workers, job['worker']) %>"><%= job['worker'].split(':')[0...2].join(':') %></a> on <b class='queue-tag'><%= job['queue'] %></b > at <b><span class="time"><%= DateTime.parse(job['failed_at']).strftime(failed_date_format) %></span></b>
|
|
9
|
+
<a href="<%= h u(:workers, job['worker']) %>"><%= h job['worker'].split(':')[0...2].join(':') %></a> on <b class='queue-tag'><%= h job['queue'] %></b > at <b><span class="time"><%= DateTime.parse(job['failed_at']).strftime(failed_date_format) %></span></b>
|
|
10
10
|
<% if job['retried_at'] %>
|
|
11
11
|
<div class='retried'>
|
|
12
12
|
Retried <b><span class="time"><%= DateTime.parse(job['retried_at']).strftime(failed_date_format) %></span></b>
|
|
13
|
-
<a href="<%= u
|
|
13
|
+
<a href="<%= h u("#{queue}/remove/#{id}") %>" class="remove" rel="remove">Remove</a>
|
|
14
14
|
</div>
|
|
15
15
|
<% else %>
|
|
16
16
|
<div class='controls'>
|
|
17
|
-
<a href="<%= u
|
|
17
|
+
<a href="<%= h u("#{queue}/requeue/#{id}") %>" rel="retry">Retry</a>
|
|
18
18
|
or
|
|
19
|
-
<a href="<%= u
|
|
19
|
+
<a href="<%= h u("#{queue}/remove/#{id}") %>" rel="remove">Remove</a>
|
|
20
20
|
</div>
|
|
21
21
|
<% end %>
|
|
22
22
|
</dd>
|
|
23
23
|
<dt>Class</dt>
|
|
24
24
|
<dd>
|
|
25
25
|
<% if job['payload'] && job['payload']['class'] %>
|
|
26
|
-
<a href="<%= u
|
|
26
|
+
<a href="<%= h u("#{queue}?class=#{job['payload']['class']}") %>">
|
|
27
27
|
<%= partial :job_class, :job => job['payload'] %>
|
|
28
28
|
</a>
|
|
29
29
|
<% else %>
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
<dt>Arguments</dt>
|
|
34
34
|
<dd><pre><%=h job['payload'] ? show_args(job['payload']['args']) : 'nil' %></pre></dd>
|
|
35
35
|
<dt>Exception</dt>
|
|
36
|
-
<dd><code><%= job['exception'] %></code></dd>
|
|
36
|
+
<dd><code><%= h job['exception'] %></code></dd>
|
|
37
37
|
<dt>Error</dt>
|
|
38
38
|
<dd class='error'>
|
|
39
39
|
<% if job['backtrace'] %>
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
<% Resque::Failure.queues.sort.each do |queue| %>
|
|
9
9
|
<tr>
|
|
10
|
-
<th><b class="queue-tag"><a href="<%= u
|
|
10
|
+
<th><b class="queue-tag"><a href="<%= h u("/failed/#{queue}") %>"><%= h queue %></a></b></th>
|
|
11
11
|
<th style="width:75px;" class="center"><%= Resque::Failure.count(queue) %></th>
|
|
12
12
|
</tr>
|
|
13
13
|
|
|
14
14
|
<% failed_class_counts(queue).sort_by { |name,_| name }.each do |k, v| %>
|
|
15
|
-
<tr id="<%= k %>">
|
|
15
|
+
<tr id="<%= h k %>">
|
|
16
16
|
<td>
|
|
17
|
-
<a href="<%= u
|
|
17
|
+
<a href="<%= h u("/failed/#{queue}?class=#{k}") %>"><span class="failed failed_class"><%= h k %></span></a>
|
|
18
18
|
</td>
|
|
19
19
|
<td style="text-align: center;" class="failed<%= (v.to_i > 1000) ? '_many' : '' %>"><%= v %></td>
|
|
20
20
|
</tr>
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<% if job['class'] == 'ActiveJob::QueueAdapters::ResqueAdapter::JobWrapper' %>
|
|
2
|
-
<code><%= job['args'].first['job_class'] %></code>
|
|
2
|
+
<code><%= h job['args'].first['job_class'] %></code>
|
|
3
3
|
<small>
|
|
4
4
|
<a href="http://edgeguides.rubyonrails.org/active_job_basics.html" rel="noopener noreferrer" target="_blank">(via ActiveJob)</a>
|
|
5
5
|
</small>
|
|
6
6
|
<% else %>
|
|
7
|
-
<code><%= job['class'] %></code>
|
|
7
|
+
<code><%= h job['class'] %></code>
|
|
8
8
|
<% end %>
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
<p class='sub'><%= page_entries_info start = params[:start].to_i, start + 20, size = redis_get_size(key) %></p>
|
|
4
4
|
|
|
5
|
-
<h1>Key "<%= key %>" is a <%= resque.redis.type key %></h1>
|
|
5
|
+
<h1>Key "<%= escape_html(key) %>" is a <%= resque.redis.type key %></h1>
|
|
6
6
|
<table>
|
|
7
7
|
<% for row in redis_get_value_as_array(key, start) %>
|
|
8
8
|
<tr>
|
|
9
9
|
<td>
|
|
10
|
-
<%= row %>
|
|
10
|
+
<%= h row %>
|
|
11
11
|
</td>
|
|
12
12
|
</tr>
|
|
13
13
|
<% end %>
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
</ul>
|
|
20
20
|
<% if Resque.redis.namespace != :resque %>
|
|
21
21
|
<abbr class="namespace" title="Resque's Redis Namespace">
|
|
22
|
-
<%= Resque.redis.namespace %>
|
|
22
|
+
<%= h Resque.redis.namespace %>
|
|
23
23
|
</abbr>
|
|
24
24
|
<% end %>
|
|
25
25
|
</div>
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
<% if defined?(@subtabs) && @subtabs %>
|
|
28
28
|
<ul class='subnav'>
|
|
29
29
|
<% for subtab in @subtabs %>
|
|
30
|
-
<li <%= class_if_current "#{current_section}/#{subtab}" %>><a href="<%= current_section %>/<%= subtab %>"><span><%= subtab %></span></a></li>
|
|
30
|
+
<li <%= class_if_current "#{current_section}/#{subtab}" %>><a href="<%= h current_section %>/<%= h subtab %>"><span><%= h subtab %></span></a></li>
|
|
31
31
|
<% end %>
|
|
32
32
|
</ul>
|
|
33
33
|
<% end %>
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
|
|
39
39
|
<div id="footer">
|
|
40
40
|
<p>Powered by <a href="http://github.com/resque/resque">Resque</a> v<%=Resque::VERSION%></p>
|
|
41
|
-
<p>Connected to Redis namespace <%= Resque.redis.namespace %> on <%= h Resque.redis_id %></p>
|
|
41
|
+
<p>Connected to Redis namespace <%= h Resque.redis.namespace %> on <%= h Resque.redis_id %></p>
|
|
42
42
|
</div>
|
|
43
43
|
|
|
44
44
|
</body>
|
|
@@ -4,19 +4,19 @@
|
|
|
4
4
|
<%if start - per_page >= 0 || start + per_page <= size%>
|
|
5
5
|
<div class='pagination'>
|
|
6
6
|
<% if start - per_page >= 0 %>
|
|
7
|
-
<a href="<%= current_page %>?start=<%= start - per_page %>" class='less'>« Previous</a>
|
|
7
|
+
<a href="<%= h current_page %>?start=<%= start - per_page %>" class='less'>« Previous</a>
|
|
8
8
|
<% end %>
|
|
9
9
|
|
|
10
10
|
<% (size / per_page.to_f).ceil.times do |page_num| %>
|
|
11
11
|
<% if start == page_num * per_page %>
|
|
12
12
|
<span><%= page_num + 1 %></span>
|
|
13
13
|
<% else %>
|
|
14
|
-
<a href="<%= current_page %>?start=<%= page_num * per_page %>"> <%= page_num + 1 %></a>
|
|
14
|
+
<a href="<%= h current_page %>?start=<%= page_num * per_page %>"> <%= page_num + 1 %></a>
|
|
15
15
|
<% end %>
|
|
16
16
|
<% end %>
|
|
17
17
|
|
|
18
18
|
<% if start + per_page < size %>
|
|
19
|
-
<a href="<%= current_page %>?start=<%= start + per_page %>" class='more'>Next »</a>
|
|
19
|
+
<a href="<%= h current_page %>?start=<%= start + per_page %>" class='more'>Next »</a>
|
|
20
20
|
<% end %>
|
|
21
21
|
</div>
|
|
22
22
|
<%end%>
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
<%= partial :job_class, :job => job['payload'] %>
|
|
2
|
-
<small><a class="queue time" href="<%=u
|
|
2
|
+
<small><a class="queue time" href="<%= h u("/working/#{worker}") %>"><%= h job['run_at'] %></a></small>
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
<% if current_queue = params[:id] %>
|
|
4
4
|
|
|
5
|
-
<h1>Pending jobs on <span class='hl'><%= h
|
|
6
|
-
<form method="POST" action="<%=u
|
|
5
|
+
<h1>Pending jobs on <span class='hl'><%= h current_queue %></span></h1>
|
|
6
|
+
<form method="POST" action="<%= h u("/queues/#{current_queue}/remove") %>" class='remove-queue'>
|
|
7
7
|
<input type='submit' name='' value='Remove Queue' class="confirmSubmission" />
|
|
8
8
|
</form>
|
|
9
9
|
<p class='sub'><%= page_entries_info start = params[:start].to_i, start + 19, size = resque.size(current_queue), 'job' %></p>
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
</tr>
|
|
37
37
|
<% resque.queues.sort_by { |q| q.to_s }.each do |queue| %>
|
|
38
38
|
<tr>
|
|
39
|
-
<td class='queue'><a class="queue" href="<%= u
|
|
39
|
+
<td class='queue'><a class="queue" href="<%= h u("queues/#{queue}") %>"><%= h queue %></a></td>
|
|
40
40
|
<td class='size'><%= resque.size queue %></td>
|
|
41
41
|
</tr>
|
|
42
42
|
<% end %>
|
|
43
43
|
<% if failed_multiple_queues? %>
|
|
44
44
|
<% Resque::Failure.queues.sort_by { |q| q.to_s }.each_with_index do |queue, i| %>
|
|
45
45
|
<tr class="<%= Resque::Failure.count(queue).zero? ? "failed" : "failure" %><%= " first_failure" if i.zero? %>">
|
|
46
|
-
<td class='queue failed'><a class="queue" href="<%= u
|
|
46
|
+
<td class='queue failed'><a class="queue" href="<%= h u("failed/#{queue}") %>"><%= h queue %></a></td>
|
|
47
47
|
<td class='size'><%= Resque::Failure.count(queue) %></td>
|
|
48
48
|
</tr>
|
|
49
49
|
<% end %>
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
<% for key, value in resque.info.to_a.sort_by { |i| i[0].to_s } %>
|
|
12
12
|
<tr>
|
|
13
13
|
<th>
|
|
14
|
-
<%= key %>
|
|
14
|
+
<%= h key %>
|
|
15
15
|
</th>
|
|
16
16
|
<td>
|
|
17
17
|
<%= h value %>
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
<% for key, value in resque.redis.redis.info.to_a.sort_by { |i| i[0].to_s } %>
|
|
28
28
|
<tr>
|
|
29
29
|
<th>
|
|
30
|
-
<%= key %>
|
|
30
|
+
<%= h key %>
|
|
31
31
|
</th>
|
|
32
32
|
<td>
|
|
33
|
-
<%= value %>
|
|
33
|
+
<%= h value %>
|
|
34
34
|
</td>
|
|
35
35
|
</tr>
|
|
36
36
|
<% end %>
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
<% elsif params[:id] == 'keys' %>
|
|
40
40
|
|
|
41
41
|
<h1>Keys owned by <%= h resque.redis_id %></h1>
|
|
42
|
-
<p class='sub'>(All keys are actually prefixed with "<%= Resque.redis.namespace %>:")</p>
|
|
42
|
+
<p class='sub'>(All keys are actually prefixed with "<%= h Resque.redis.namespace %>:")</p>
|
|
43
43
|
<table class='stats'>
|
|
44
44
|
<tr>
|
|
45
45
|
<th>key</th>
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
<% for key in resque.keys.sort %>
|
|
50
50
|
<tr>
|
|
51
51
|
<th>
|
|
52
|
-
<a href="<%=u
|
|
52
|
+
<a href="<%= h u("/stats/keys/#{key}") %>"><%= h key %></a>
|
|
53
53
|
</th>
|
|
54
54
|
<td><%= resque.redis.type key %></td>
|
|
55
55
|
<td><%= redis_get_size key %></td>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
<% if params[:id] && worker = Resque::Worker.find(params[:id]) %>
|
|
4
4
|
|
|
5
|
-
<h1>Worker <%= worker %></h1>
|
|
5
|
+
<h1>Worker <%= h worker %></h1>
|
|
6
6
|
<table class='workers'>
|
|
7
7
|
<tr>
|
|
8
8
|
<th> </th>
|
|
@@ -16,14 +16,14 @@
|
|
|
16
16
|
<th>Processing</th>
|
|
17
17
|
</tr>
|
|
18
18
|
<tr>
|
|
19
|
-
<td class='icon'><img src="<%=u
|
|
19
|
+
<td class='icon'><img src="<%= h u(state = worker.state) %>.png" alt="<%= h state %>" title="<%= h state %>"></td>
|
|
20
20
|
|
|
21
21
|
<% host, pid, queues = worker.to_s.split(':') %>
|
|
22
|
-
<td><%= host %></td>
|
|
23
|
-
<td><%= pid %></td>
|
|
24
|
-
<td><span class="time"><%= worker.started %></span></td>
|
|
25
|
-
<td><span class="time"><%= worker.heartbeat %></span></td>
|
|
26
|
-
<td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
|
|
22
|
+
<td><%= h host %></td>
|
|
23
|
+
<td><%= h pid %></td>
|
|
24
|
+
<td><span class="time"><%= h worker.started %></span></td>
|
|
25
|
+
<td><span class="time"><%= h worker.heartbeat %></span></td>
|
|
26
|
+
<td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + h(u("/queues/#{q}")) + '">' + h(q) + '</a>'}.join('') %></td>
|
|
27
27
|
<td><%= worker.processed %></td>
|
|
28
28
|
<td><%= worker.failed %></td>
|
|
29
29
|
<td class='process'>
|
|
@@ -60,11 +60,11 @@
|
|
|
60
60
|
</tr>
|
|
61
61
|
<% for worker in (workers = workers.sort_by { |w| w.to_s }) %>
|
|
62
62
|
<tr class="<%=state = worker.state%>">
|
|
63
|
-
<td class='icon'><img src="<%=u
|
|
63
|
+
<td class='icon'><img src="<%= h u(state) %>.png" alt="<%= h state %>" title="<%= h state %>"></td>
|
|
64
64
|
|
|
65
65
|
<% host, pid, queues = worker.to_s.split(':') %>
|
|
66
|
-
<td class='where'><a href="<%=u
|
|
67
|
-
<td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + u("/queues/#{q}") + '">' + q + '</a>'}.join('') %></td>
|
|
66
|
+
<td class='where'><a href="<%= h u("workers/#{worker}") %>"><%= h host %>:<%= h pid %></a></td>
|
|
67
|
+
<td class='queues'><%= queues.split(',').map { |q| '<a class="queue-tag" href="' + h(u("/queues/#{q}")) + '">' + h(q) + '</a>'}.join('') %></td>
|
|
68
68
|
|
|
69
69
|
<td class='process'>
|
|
70
70
|
<% data = worker.processing || {} %>
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
</tr>
|
|
96
96
|
<% for hostname, workers in worker_hosts.sort_by { |h,w| h } %>
|
|
97
97
|
<tr>
|
|
98
|
-
<td class='queue'><a class="queue" href="<%= u
|
|
98
|
+
<td class='queue'><a class="queue" href="<%= h u("workers/#{hostname}") %>"><%= h hostname %></a></td>
|
|
99
99
|
<td class='size'><%= workers.size %></td>
|
|
100
100
|
</tr>
|
|
101
101
|
<% end %>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<% if params[:id] && (current_worker = Resque::Worker.find(params[:id])) && (data = current_worker.job) %>
|
|
2
|
-
<h1><%= current_worker %>'s job</h1>
|
|
2
|
+
<h1><%= h current_worker %>'s job</h1>
|
|
3
3
|
|
|
4
4
|
<table>
|
|
5
5
|
<tr>
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
<tr>
|
|
14
14
|
<td><img src="<%=u 'working.png' %>" alt="working" title="working"></td>
|
|
15
15
|
<% host, pid, _ = current_worker.to_s.split(':') %>
|
|
16
|
-
<td><a href="<%=u
|
|
16
|
+
<td><a href="<%= h u("/workers/#{current_worker}") %>"><%= h host %>:<%= h pid %></a></td>
|
|
17
17
|
<% queue = data['queue'] %>
|
|
18
|
-
<td><a class="queue" href="<%=u
|
|
19
|
-
<td><span class="time"><%= data['run_at'] %></span></td>
|
|
18
|
+
<td><a class="queue" href="<%= h u("/queues/#{queue}") %>"><%= h queue %></a></td>
|
|
19
|
+
<td><span class="time"><%= h data['run_at'] %></span></td>
|
|
20
20
|
<% payload = data.key?('payload') ? data['payload'] : {} %>
|
|
21
21
|
<td>
|
|
22
|
-
<code><%= payload.key?('class') ? payload['class'] : "—" %></code>
|
|
22
|
+
<code><%= payload.key?('class') ? h(payload['class']) : "—" %></code>
|
|
23
23
|
</td>
|
|
24
24
|
<td><pre><%=h payload.key?('args') ? show_args(payload['args']) : "—" %></pre></td>
|
|
25
25
|
</tr>
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
|
|
52
52
|
<% worker_jobs.sort_by { |_w, j| j['run_at'] ? j['run_at'].to_s() : '' }.each do |worker, job| %>
|
|
53
53
|
<tr>
|
|
54
|
-
<td class='icon'><img src="<%=u
|
|
54
|
+
<td class='icon'><img src="<%= h u(state = worker.state) %>.png" alt="<%= h state %>" title="<%= h state %>"></td>
|
|
55
55
|
<% host, pid, _queues = worker.to_s.split(':') %>
|
|
56
|
-
<td class='where'><a href="<%=u
|
|
56
|
+
<td class='where'><a href="<%= h u("/workers/#{worker}") %>"><%= h host %>:<%= h pid %></a></td>
|
|
57
57
|
<td class='queues queue'>
|
|
58
|
-
<a class="queue-tag" href="<%=u
|
|
58
|
+
<a class="queue-tag" href="<%= h u("/queues/#{job['queue']}") %>"><%= h job['queue'] %></a>
|
|
59
59
|
</td>
|
|
60
60
|
<td class='process'>
|
|
61
61
|
<% if job['queue'] %>
|
data/lib/resque/server.rb
CHANGED
data/lib/resque/server_helper.rb
CHANGED
|
@@ -29,7 +29,7 @@ module Resque
|
|
|
29
29
|
def tab(name)
|
|
30
30
|
dname = name.to_s.downcase
|
|
31
31
|
path = url_path(dname)
|
|
32
|
-
"<li #{class_if_current(path)}><a href='#{path.gsub(" ", "_")}'>#{name}</a></li>"
|
|
32
|
+
"<li #{class_if_current(path)}><a href='#{h path.gsub(" ", "_")}'>#{h name}</a></li>"
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def tabs
|
|
@@ -112,7 +112,7 @@ module Resque
|
|
|
112
112
|
if defined?(@polling) && @polling
|
|
113
113
|
text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
|
|
114
114
|
else
|
|
115
|
-
text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll!!</a>"
|
|
115
|
+
text = "<a href='#{h u(request.path_info)}.poll' rel='poll'>Live Poll!!</a>"
|
|
116
116
|
end
|
|
117
117
|
"<p class='poll'>#{text}</p>"
|
|
118
118
|
end
|
data/lib/resque/tasks.rb
CHANGED
|
@@ -17,7 +17,11 @@ namespace :resque do
|
|
|
17
17
|
|
|
18
18
|
worker.prepare
|
|
19
19
|
worker.log "Starting worker #{worker}"
|
|
20
|
-
|
|
20
|
+
# will block until a shutdown signal is received
|
|
21
|
+
worker.work(ENV["INTERVAL"],
|
|
22
|
+
max_interval: ENV['MAX_INTERVAL'],
|
|
23
|
+
min_interval: ENV['MIN_INTERVAL'],
|
|
24
|
+
backoff_interval: ENV['BACKOFF_INTERVAL'])
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
desc "Start multiple Resque workers. Should only be used in dev mode."
|
data/lib/resque/version.rb
CHANGED
data/lib/resque/web_runner.rb
CHANGED
|
@@ -3,6 +3,10 @@ require 'logger'
|
|
|
3
3
|
require 'optparse'
|
|
4
4
|
require 'fileutils'
|
|
5
5
|
require 'rack'
|
|
6
|
+
begin
|
|
7
|
+
require 'rackup'
|
|
8
|
+
rescue LoadError
|
|
9
|
+
end
|
|
6
10
|
require 'resque/server'
|
|
7
11
|
|
|
8
12
|
# only used with `bin/resque-web`
|
|
@@ -30,7 +34,7 @@ module Resque
|
|
|
30
34
|
|
|
31
35
|
@args = load_options(runtime_args)
|
|
32
36
|
|
|
33
|
-
@rack_handler = (s = options[:rack_handler]) ?
|
|
37
|
+
@rack_handler = (s = options[:rack_handler]) ? self.class.get_rackup_or_rack_handler.get(s) : setup_rack_handler
|
|
34
38
|
|
|
35
39
|
case option_parser.command
|
|
36
40
|
when :help
|
|
@@ -81,7 +85,8 @@ module Resque
|
|
|
81
85
|
end
|
|
82
86
|
|
|
83
87
|
def url
|
|
84
|
-
"
|
|
88
|
+
h = host.include?(':') ? "[#{host}]" : host
|
|
89
|
+
"http://#{h}:#{port}"
|
|
85
90
|
end
|
|
86
91
|
|
|
87
92
|
def before_run
|
|
@@ -270,6 +275,10 @@ module Resque
|
|
|
270
275
|
self.class.logger
|
|
271
276
|
end
|
|
272
277
|
|
|
278
|
+
def self.get_rackup_or_rack_handler
|
|
279
|
+
defined?(::Rackup::Handler) && ::Rack.release >= '3' ? ::Rackup::Handler : ::Rack::Handler
|
|
280
|
+
end
|
|
281
|
+
|
|
273
282
|
private
|
|
274
283
|
def setup_rack_handler
|
|
275
284
|
# First try to set Rack handler via a special hook we honor
|
|
@@ -284,24 +293,25 @@ module Resque
|
|
|
284
293
|
handler = nil
|
|
285
294
|
@app.server.each do |server|
|
|
286
295
|
begin
|
|
287
|
-
handler =
|
|
296
|
+
handler = self.class.get_rackup_or_rack_handler.get(server)
|
|
288
297
|
break
|
|
289
298
|
rescue LoadError, NameError
|
|
290
299
|
next
|
|
291
300
|
end
|
|
292
301
|
end
|
|
293
|
-
raise 'No available Rack handler (e.g. WEBrick,
|
|
302
|
+
raise 'No available Rack handler (e.g. WEBrick, Puma, etc.) was found.' if handler.nil?
|
|
294
303
|
|
|
295
304
|
handler
|
|
296
305
|
|
|
297
306
|
# :server might be set explicitly to a single option like "mongrel"
|
|
298
307
|
else
|
|
299
|
-
|
|
308
|
+
self.class.get_rackup_or_rack_handler.get(@app.server)
|
|
300
309
|
end
|
|
301
310
|
|
|
302
|
-
# If all else fails, we'll use
|
|
311
|
+
# If all else fails, we'll use Puma
|
|
303
312
|
else
|
|
304
|
-
JRUBY ?
|
|
313
|
+
rack_server = JRUBY ? 'webrick' : 'puma'
|
|
314
|
+
self.class.get_rackup_or_rack_handler.get(rack_server)
|
|
305
315
|
end
|
|
306
316
|
end
|
|
307
317
|
|
data/lib/resque/worker.rb
CHANGED
|
@@ -143,6 +143,7 @@ module Resque
|
|
|
143
143
|
def initialize(*queues)
|
|
144
144
|
@shutdown = nil
|
|
145
145
|
@paused = nil
|
|
146
|
+
@cached_pause_value = nil
|
|
146
147
|
@before_first_fork_hook_ran = false
|
|
147
148
|
|
|
148
149
|
@heartbeat_thread = nil
|
|
@@ -237,20 +238,43 @@ module Resque
|
|
|
237
238
|
# The default is 5 seconds, but for a semi-active site you may
|
|
238
239
|
# want to use a smaller value.
|
|
239
240
|
#
|
|
241
|
+
# Can also be passed 3 interval floats: max, min, backoff.
|
|
242
|
+
# The actual sleep amount will float between these min/max
|
|
243
|
+
# bounds.
|
|
244
|
+
#
|
|
245
|
+
# If a job is picked up we sleep for the minimum amount of
|
|
246
|
+
# time, but as the queues empty we increase the backoff to the
|
|
247
|
+
# max interval. This prevents idle workers from hammering the
|
|
248
|
+
# redis server with lpop requests.
|
|
249
|
+
#
|
|
240
250
|
# Also accepts a block which will be passed the job as soon as it
|
|
241
251
|
# has completed processing. Useful for testing.
|
|
242
|
-
def work(interval = 5.0,
|
|
243
|
-
|
|
252
|
+
def work(interval = 5.0,
|
|
253
|
+
min_interval: nil, # defaults to interval
|
|
254
|
+
max_interval: nil, # defaults to interval
|
|
255
|
+
backoff_interval: nil, # defaults to 0.1
|
|
256
|
+
&block)
|
|
257
|
+
interval = Float(interval || 5.0)
|
|
258
|
+
max_interval = Float(max_interval || interval)
|
|
259
|
+
min_interval = Float(min_interval || interval).clamp(nil, max_interval)
|
|
260
|
+
backoff_interval = Float(backoff_interval || 0.1).clamp(nil, max_interval)
|
|
261
|
+
interval = interval.clamp(min_interval, max_interval)
|
|
244
262
|
startup
|
|
245
263
|
|
|
246
264
|
loop do
|
|
247
265
|
break if shutdown?
|
|
248
266
|
|
|
249
|
-
|
|
267
|
+
if work_one_job(&block)
|
|
268
|
+
interval = min_interval
|
|
269
|
+
else
|
|
250
270
|
state_change
|
|
251
271
|
break if interval.zero?
|
|
272
|
+
|
|
273
|
+
interval = (interval + backoff_interval)
|
|
274
|
+
.clamp(nil, max_interval)
|
|
275
|
+
|
|
252
276
|
log_with_severity :debug, "Sleeping for #{interval} seconds"
|
|
253
|
-
procline
|
|
277
|
+
procline @cached_pause_value ? "Paused" : "Waiting for #{queues.join(',')}"
|
|
254
278
|
sleep interval
|
|
255
279
|
end
|
|
256
280
|
end
|
|
@@ -260,6 +284,7 @@ module Resque
|
|
|
260
284
|
rescue Exception => exception
|
|
261
285
|
return if exception.class == SystemExit && !@child && run_at_exit_hooks
|
|
262
286
|
log_with_severity :error, "Failed to start worker : #{exception.inspect}"
|
|
287
|
+
log_with_severity :error, exception.backtrace.join("\n")
|
|
263
288
|
unregister_worker(exception)
|
|
264
289
|
run_hook :worker_exit
|
|
265
290
|
end
|
|
@@ -441,6 +466,8 @@ module Resque
|
|
|
441
466
|
def shutdown
|
|
442
467
|
log_with_severity :info, 'Exiting...'
|
|
443
468
|
@shutdown = true
|
|
469
|
+
run_hook :shutdown
|
|
470
|
+
true
|
|
444
471
|
end
|
|
445
472
|
|
|
446
473
|
# Kill the child and shutdown immediately.
|
|
@@ -579,7 +606,7 @@ module Resque
|
|
|
579
606
|
|
|
580
607
|
# are we paused?
|
|
581
608
|
def paused?
|
|
582
|
-
@paused || redis.get('pause-all-workers').to_s.strip.downcase == 'true'
|
|
609
|
+
@cached_pause_value = @paused || redis.get('pause-all-workers').to_s.strip.downcase == 'true'
|
|
583
610
|
end
|
|
584
611
|
|
|
585
612
|
# Stop processing jobs after the current one has completed (if we're
|
data/lib/resque.rb
CHANGED
|
@@ -31,8 +31,15 @@ module Resque
|
|
|
31
31
|
|
|
32
32
|
# Given a Ruby object, returns a string suitable for storage in a
|
|
33
33
|
# queue.
|
|
34
|
+
#
|
|
35
|
+
# multi_json has renamed its core methods twice: first encode/decode became
|
|
36
|
+
# dump/load, then multi_json 1.21 renamed dump/load to generate/parse. Old
|
|
37
|
+
# names keep working as deprecated aliases. Check the newest name first so
|
|
38
|
+
# we prefer it while staying compatible with older installed versions.
|
|
34
39
|
def encode(object)
|
|
35
|
-
if MultiJson.respond_to?(:
|
|
40
|
+
if MultiJson.respond_to?(:generate) && MultiJson.respond_to?(:parse)
|
|
41
|
+
MultiJson.generate object
|
|
42
|
+
elsif MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
|
36
43
|
MultiJson.dump object
|
|
37
44
|
else
|
|
38
45
|
MultiJson.encode object
|
|
@@ -40,16 +47,20 @@ module Resque
|
|
|
40
47
|
end
|
|
41
48
|
|
|
42
49
|
# Given a string, returns a Ruby object.
|
|
50
|
+
#
|
|
51
|
+
# See `Resque.encode`, above, for why generate/parse are checked before dump/load.
|
|
43
52
|
def decode(object)
|
|
44
53
|
return unless object
|
|
45
54
|
|
|
46
55
|
begin
|
|
47
|
-
if MultiJson.respond_to?(:
|
|
56
|
+
if MultiJson.respond_to?(:generate) && MultiJson.respond_to?(:parse)
|
|
57
|
+
MultiJson.parse object
|
|
58
|
+
elsif MultiJson.respond_to?(:dump) && MultiJson.respond_to?(:load)
|
|
48
59
|
MultiJson.load object
|
|
49
60
|
else
|
|
50
61
|
MultiJson.decode object
|
|
51
62
|
end
|
|
52
|
-
rescue
|
|
63
|
+
rescue MultiJson::DecodeError => e
|
|
53
64
|
raise Helpers::DecodeException, e.message, e.backtrace
|
|
54
65
|
end
|
|
55
66
|
end
|
|
@@ -251,7 +262,7 @@ module Resque
|
|
|
251
262
|
register_hook(:before_fork, block)
|
|
252
263
|
end
|
|
253
264
|
|
|
254
|
-
# The `after_fork` hook will be run in the child process and is passed
|
|
265
|
+
# The `after_fork` hook will be run in the **child** process and is passed
|
|
255
266
|
# the current job. Any changes you make, therefore, will only live as
|
|
256
267
|
# long as the job currently being processed.
|
|
257
268
|
#
|
|
@@ -266,7 +277,7 @@ module Resque
|
|
|
266
277
|
register_hook(:after_fork, block)
|
|
267
278
|
end
|
|
268
279
|
|
|
269
|
-
# The `before_pause` hook will be run in the parent process before the
|
|
280
|
+
# The `before_pause` hook will be run in the **parent** process before the
|
|
270
281
|
# worker has paused processing (via #pause_processing or SIGUSR2).
|
|
271
282
|
def before_pause(&block)
|
|
272
283
|
block ? register_hook(:before_pause, block) : hooks(:before_pause)
|
|
@@ -277,7 +288,7 @@ module Resque
|
|
|
277
288
|
register_hook(:before_pause, block)
|
|
278
289
|
end
|
|
279
290
|
|
|
280
|
-
# The `after_pause` hook will be run in the parent process after the
|
|
291
|
+
# The `after_pause` hook will be run in the **parent** process after the
|
|
281
292
|
# worker has paused (via SIGCONT).
|
|
282
293
|
def after_pause(&block)
|
|
283
294
|
block ? register_hook(:after_pause, block) : hooks(:after_pause)
|
|
@@ -316,6 +327,20 @@ module Resque
|
|
|
316
327
|
register_hook(:worker_exit, block)
|
|
317
328
|
end
|
|
318
329
|
|
|
330
|
+
# The `shutdown` hook will be run in the **parent** process
|
|
331
|
+
# when the worker has received a signal to stop processing
|
|
332
|
+
#
|
|
333
|
+
# Call with a block to register a hook.
|
|
334
|
+
# Call with no arguments to return all registered hooks.
|
|
335
|
+
def shutdown(&block)
|
|
336
|
+
block ? register_hook(:shutdown, block) : hooks(:shutdown)
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
# Register a shutdown proc.
|
|
340
|
+
def shutdown=(block)
|
|
341
|
+
register_hook(:shutdown, block)
|
|
342
|
+
end
|
|
343
|
+
|
|
319
344
|
def to_s
|
|
320
345
|
"Resque Client connected to #{redis_id}"
|
|
321
346
|
end
|
metadata
CHANGED
|
@@ -1,18 +1,45 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resque
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Wanstrath
|
|
8
8
|
- Steve Klabnik
|
|
9
9
|
- Terence Lee
|
|
10
10
|
- Michael Bianco
|
|
11
|
-
autorequire:
|
|
12
11
|
bindir: bin
|
|
13
12
|
cert_chain: []
|
|
14
|
-
date:
|
|
13
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
15
14
|
dependencies:
|
|
15
|
+
- !ruby/object:Gem::Dependency
|
|
16
|
+
name: base64
|
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
|
18
|
+
requirements:
|
|
19
|
+
- - "~>"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0.1'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - "~>"
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '0.1'
|
|
29
|
+
- !ruby/object:Gem::Dependency
|
|
30
|
+
name: logger
|
|
31
|
+
requirement: !ruby/object:Gem::Requirement
|
|
32
|
+
requirements:
|
|
33
|
+
- - ">="
|
|
34
|
+
- !ruby/object:Gem::Version
|
|
35
|
+
version: '0'
|
|
36
|
+
type: :runtime
|
|
37
|
+
prerelease: false
|
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
39
|
+
requirements:
|
|
40
|
+
- - ">="
|
|
41
|
+
- !ruby/object:Gem::Version
|
|
42
|
+
version: '0'
|
|
16
43
|
- !ruby/object:Gem::Dependency
|
|
17
44
|
name: redis-namespace
|
|
18
45
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -27,20 +54,34 @@ dependencies:
|
|
|
27
54
|
- - "~>"
|
|
28
55
|
- !ruby/object:Gem::Version
|
|
29
56
|
version: '1.6'
|
|
57
|
+
- !ruby/object:Gem::Dependency
|
|
58
|
+
name: redis
|
|
59
|
+
requirement: !ruby/object:Gem::Requirement
|
|
60
|
+
requirements:
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: '4.0'
|
|
64
|
+
type: :runtime
|
|
65
|
+
prerelease: false
|
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - ">="
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '4.0'
|
|
30
71
|
- !ruby/object:Gem::Dependency
|
|
31
72
|
name: sinatra
|
|
32
73
|
requirement: !ruby/object:Gem::Requirement
|
|
33
74
|
requirements:
|
|
34
75
|
- - ">="
|
|
35
76
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: 0
|
|
77
|
+
version: '2.0'
|
|
37
78
|
type: :runtime
|
|
38
79
|
prerelease: false
|
|
39
80
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
81
|
requirements:
|
|
41
82
|
- - ">="
|
|
42
83
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: 0
|
|
84
|
+
version: '2.0'
|
|
44
85
|
- !ruby/object:Gem::Dependency
|
|
45
86
|
name: multi_json
|
|
46
87
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -70,7 +111,7 @@ dependencies:
|
|
|
70
111
|
- !ruby/object:Gem::Version
|
|
71
112
|
version: '1'
|
|
72
113
|
- !ruby/object:Gem::Dependency
|
|
73
|
-
name:
|
|
114
|
+
name: puma
|
|
74
115
|
requirement: !ruby/object:Gem::Requirement
|
|
75
116
|
requirements:
|
|
76
117
|
- - ">="
|
|
@@ -127,6 +168,7 @@ files:
|
|
|
127
168
|
- Rakefile
|
|
128
169
|
- bin/resque
|
|
129
170
|
- bin/resque-web
|
|
171
|
+
- lib/active_job/queue_adapters/resque_adapter.rb
|
|
130
172
|
- lib/resque.rb
|
|
131
173
|
- lib/resque/data_store.rb
|
|
132
174
|
- lib/resque/errors.rb
|
|
@@ -186,7 +228,6 @@ licenses:
|
|
|
186
228
|
metadata:
|
|
187
229
|
changelog_uri: https://github.com/resque/resque/blob/master/HISTORY.md
|
|
188
230
|
rubygems_mfa_required: 'true'
|
|
189
|
-
post_install_message:
|
|
190
231
|
rdoc_options:
|
|
191
232
|
- "--charset=UTF-8"
|
|
192
233
|
require_paths:
|
|
@@ -195,15 +236,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
195
236
|
requirements:
|
|
196
237
|
- - ">="
|
|
197
238
|
- !ruby/object:Gem::Version
|
|
198
|
-
version:
|
|
239
|
+
version: 3.0.0
|
|
199
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
241
|
requirements:
|
|
201
242
|
- - ">="
|
|
202
243
|
- !ruby/object:Gem::Version
|
|
203
244
|
version: '0'
|
|
204
245
|
requirements: []
|
|
205
|
-
rubygems_version:
|
|
206
|
-
signing_key:
|
|
246
|
+
rubygems_version: 4.0.6
|
|
207
247
|
specification_version: 4
|
|
208
248
|
summary: Resque is a Redis-backed queueing system.
|
|
209
249
|
test_files: []
|