resque 2.0.0 → 2.6.0
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 +102 -0
- data/README.markdown +419 -515
- data/bin/resque-web +10 -26
- data/lib/resque/data_store.rb +32 -29
- data/lib/resque/failure/multiple.rb +6 -2
- data/lib/resque/failure/redis.rb +1 -1
- data/lib/resque/failure.rb +6 -0
- data/lib/resque/job.rb +2 -2
- data/lib/resque/logging.rb +1 -1
- data/lib/resque/railtie.rb +10 -0
- data/lib/resque/server/public/jquery-3.6.0.min.js +2 -0
- data/lib/resque/server/public/main.js +3 -0
- data/lib/resque/server/public/ranger.js +7 -4
- data/lib/resque/server/public/style.css +3 -3
- data/lib/resque/server/views/error.erb +1 -1
- data/lib/resque/server/views/failed.erb +9 -3
- data/lib/resque/server/views/job_class.erb +3 -1
- data/lib/resque/server/views/key_string.erb +1 -1
- data/lib/resque/server/views/layout.erb +4 -3
- data/lib/resque/server/views/next_more.erb +14 -14
- data/lib/resque/server/views/queues.erb +3 -3
- data/lib/resque/server/views/stats.erb +4 -4
- data/lib/resque/server/views/working.erb +1 -1
- data/lib/resque/server.rb +7 -113
- data/lib/resque/server_helper.rb +185 -0
- data/lib/resque/stat.rb +4 -4
- data/lib/resque/tasks.rb +2 -2
- data/lib/resque/version.rb +1 -1
- data/lib/resque/web_runner.rb +374 -0
- data/lib/resque/worker.rb +56 -31
- data/lib/resque.rb +39 -10
- data/lib/tasks/redis.rake +10 -10
- metadata +41 -23
- data/lib/resque/server/helpers.rb +0 -64
- data/lib/resque/server/public/jquery-1.12.4.min.js +0 -5
- data/lib/resque/server/test_helper.rb +0 -19
@@ -2,21 +2,21 @@
|
|
2
2
|
<% # without a default value %>
|
3
3
|
<% per_page ||= 20 %>
|
4
4
|
<%if start - per_page >= 0 || start + per_page <= size%>
|
5
|
-
<
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
<div class='pagination'>
|
6
|
+
<% if start - per_page >= 0 %>
|
7
|
+
<a href="<%= current_page %>?start=<%= start - per_page %>" class='less'>« Previous</a>
|
8
|
+
<% end %>
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
<% (size / per_page.to_f).ceil.times do |page_num| %>
|
11
|
+
<% if start == page_num * per_page %>
|
12
|
+
<span><%= page_num + 1 %></span>
|
13
|
+
<% else %>
|
14
|
+
<a href="<%= current_page %>?start=<%= page_num * per_page %>"> <%= page_num + 1 %></a>
|
15
|
+
<% end %>
|
15
16
|
<% end %>
|
16
|
-
<% end %>
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
</
|
18
|
+
<% if start + per_page < size %>
|
19
|
+
<a href="<%= current_page %>?start=<%= start + per_page %>" class='more'>Next »</a>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
22
22
|
<%end%>
|
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
<% if current_queue = params[:id] %>
|
4
4
|
|
5
|
-
<h1>Pending jobs on <span class='hl'><%= current_queue %></span></h1>
|
6
|
-
<form method="POST" action="<%=u "/queues/#{current_queue}/remove" %>" class='remove-queue'>
|
7
|
-
<input type='submit' name='' value='Remove Queue'
|
5
|
+
<h1>Pending jobs on <span class='hl'><%= h escape_html(current_queue) %></span></h1>
|
6
|
+
<form method="POST" action="<%=u "/queues/#{escape_html(current_queue)}/remove" %>" class='remove-queue'>
|
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>
|
10
10
|
<table class='jobs'>
|
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
<% elsif params[:id] == "resque" %>
|
8
8
|
|
9
|
-
<h1><%= resque %></h1>
|
9
|
+
<h1><%= h resque %></h1>
|
10
10
|
<table class='stats'>
|
11
11
|
<% for key, value in resque.info.to_a.sort_by { |i| i[0].to_s } %>
|
12
12
|
<tr>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<%= key %>
|
15
15
|
</th>
|
16
16
|
<td>
|
17
|
-
<%= value %>
|
17
|
+
<%= h value %>
|
18
18
|
</td>
|
19
19
|
</tr>
|
20
20
|
<% end %>
|
@@ -22,7 +22,7 @@
|
|
22
22
|
|
23
23
|
<% elsif params[:id] == 'redis' %>
|
24
24
|
|
25
|
-
<h1><%= resque.redis_id %></h1>
|
25
|
+
<h1><%= h resque.redis_id %></h1>
|
26
26
|
<table class='stats'>
|
27
27
|
<% for key, value in resque.redis.redis.info.to_a.sort_by { |i| i[0].to_s } %>
|
28
28
|
<tr>
|
@@ -38,7 +38,7 @@
|
|
38
38
|
|
39
39
|
<% elsif params[:id] == 'keys' %>
|
40
40
|
|
41
|
-
<h1>Keys owned by <%= resque %></h1>
|
41
|
+
<h1>Keys owned by <%= h resque.redis_id %></h1>
|
42
42
|
<p class='sub'>(All keys are actually prefixed with "<%= Resque.redis.namespace %>:")</p>
|
43
43
|
<table class='stats'>
|
44
44
|
<tr>
|
@@ -21,7 +21,7 @@
|
|
21
21
|
<td>
|
22
22
|
<code><%= payload.key?('class') ? payload['class'] : "—" %></code>
|
23
23
|
</td>
|
24
|
-
<td><%=h payload.key?('args') ? payload['args']
|
24
|
+
<td><pre><%=h payload.key?('args') ? show_args(payload['args']) : "—" %></pre></td>
|
25
25
|
</tr>
|
26
26
|
</table>
|
27
27
|
|
data/lib/resque/server.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'sinatra/base'
|
2
2
|
require 'tilt/erb'
|
3
3
|
require 'resque'
|
4
|
+
require 'resque/server_helper'
|
4
5
|
require 'resque/version'
|
5
6
|
require 'time'
|
6
7
|
require 'yaml'
|
@@ -11,8 +12,6 @@ end
|
|
11
12
|
|
12
13
|
module Resque
|
13
14
|
class Server < Sinatra::Base
|
14
|
-
require 'resque/server/helpers'
|
15
|
-
|
16
15
|
dir = File.dirname(File.expand_path(__FILE__))
|
17
16
|
|
18
17
|
set :views, "#{dir}/server/views"
|
@@ -26,117 +25,7 @@ module Resque
|
|
26
25
|
set :static, true
|
27
26
|
|
28
27
|
helpers do
|
29
|
-
include
|
30
|
-
alias_method :h, :escape_html
|
31
|
-
|
32
|
-
def current_section
|
33
|
-
url_path request.path_info.sub('/','').split('/')[0].downcase
|
34
|
-
end
|
35
|
-
|
36
|
-
def current_page
|
37
|
-
url_path request.path_info.sub('/','')
|
38
|
-
end
|
39
|
-
|
40
|
-
def url_path(*path_parts)
|
41
|
-
[ url_prefix, path_prefix, path_parts ].join("/").squeeze('/')
|
42
|
-
end
|
43
|
-
alias_method :u, :url_path
|
44
|
-
|
45
|
-
def path_prefix
|
46
|
-
request.env['SCRIPT_NAME']
|
47
|
-
end
|
48
|
-
|
49
|
-
def class_if_current(path = '')
|
50
|
-
'class="current"' if current_page[0, path.size] == path
|
51
|
-
end
|
52
|
-
|
53
|
-
def tab(name)
|
54
|
-
dname = name.to_s.downcase
|
55
|
-
path = url_path(dname)
|
56
|
-
"<li #{class_if_current(path)}><a href='#{path}'>#{name}</a></li>"
|
57
|
-
end
|
58
|
-
|
59
|
-
def tabs
|
60
|
-
Resque::Server.tabs
|
61
|
-
end
|
62
|
-
|
63
|
-
def url_prefix
|
64
|
-
Resque::Server.url_prefix
|
65
|
-
end
|
66
|
-
|
67
|
-
def redis_get_size(key)
|
68
|
-
case Resque.redis.type(key)
|
69
|
-
when 'none'
|
70
|
-
[]
|
71
|
-
when 'list'
|
72
|
-
Resque.redis.llen(key)
|
73
|
-
when 'set'
|
74
|
-
Resque.redis.scard(key)
|
75
|
-
when 'string'
|
76
|
-
Resque.redis.get(key).length
|
77
|
-
when 'zset'
|
78
|
-
Resque.redis.zcard(key)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
def redis_get_value_as_array(key, start=0)
|
83
|
-
case Resque.redis.type(key)
|
84
|
-
when 'none'
|
85
|
-
[]
|
86
|
-
when 'list'
|
87
|
-
Resque.redis.lrange(key, start, start + 20)
|
88
|
-
when 'set'
|
89
|
-
Resque.redis.smembers(key)[start..(start + 20)]
|
90
|
-
when 'string'
|
91
|
-
[Resque.redis.get(key)]
|
92
|
-
when 'zset'
|
93
|
-
Resque.redis.zrange(key, start, start + 20)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
def show_args(args)
|
98
|
-
Array(args).map do |a|
|
99
|
-
a.to_yaml
|
100
|
-
end.join("\n")
|
101
|
-
rescue
|
102
|
-
args.to_s
|
103
|
-
end
|
104
|
-
|
105
|
-
def worker_hosts
|
106
|
-
@worker_hosts ||= worker_hosts!
|
107
|
-
end
|
108
|
-
|
109
|
-
def worker_hosts!
|
110
|
-
hosts = Hash.new { [] }
|
111
|
-
|
112
|
-
Resque.workers.each do |worker|
|
113
|
-
host, _ = worker.to_s.split(':')
|
114
|
-
hosts[host] += [worker.to_s]
|
115
|
-
end
|
116
|
-
|
117
|
-
hosts
|
118
|
-
end
|
119
|
-
|
120
|
-
def partial?
|
121
|
-
@partial
|
122
|
-
end
|
123
|
-
|
124
|
-
def partial(template, local_vars = {})
|
125
|
-
@partial = true
|
126
|
-
erb(template.to_sym, {:layout => false}, local_vars)
|
127
|
-
ensure
|
128
|
-
@partial = false
|
129
|
-
end
|
130
|
-
|
131
|
-
def poll
|
132
|
-
if defined?(@polling) && @polling
|
133
|
-
text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
|
134
|
-
else
|
135
|
-
text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll</a>"
|
136
|
-
end
|
137
|
-
"<p class='poll'>#{text}</p>"
|
138
|
-
end
|
139
|
-
|
28
|
+
include Resque::ServerHelper
|
140
29
|
end
|
141
30
|
|
142
31
|
def show(page, layout = true)
|
@@ -205,6 +94,11 @@ module Resque
|
|
205
94
|
redirect u('failed')
|
206
95
|
end
|
207
96
|
|
97
|
+
post "/failed/clear_retried" do
|
98
|
+
Resque::Failure.clear_retried
|
99
|
+
redirect u('failed')
|
100
|
+
end
|
101
|
+
|
208
102
|
post "/failed/:queue/clear" do
|
209
103
|
Resque::Failure.clear params[:queue]
|
210
104
|
redirect u('failed')
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'rack/utils'
|
2
|
+
|
3
|
+
module Resque
|
4
|
+
module ServerHelper
|
5
|
+
include Rack::Utils
|
6
|
+
alias_method :h, :escape_html
|
7
|
+
|
8
|
+
def current_section
|
9
|
+
url_path request.path_info.sub('/','').split('/')[0].downcase
|
10
|
+
end
|
11
|
+
|
12
|
+
def current_page
|
13
|
+
url_path request.path_info.sub('/','')
|
14
|
+
end
|
15
|
+
|
16
|
+
def url_path(*path_parts)
|
17
|
+
[ url_prefix, path_prefix, path_parts ].join("/").squeeze('/')
|
18
|
+
end
|
19
|
+
alias_method :u, :url_path
|
20
|
+
|
21
|
+
def path_prefix
|
22
|
+
request.env['SCRIPT_NAME']
|
23
|
+
end
|
24
|
+
|
25
|
+
def class_if_current(path = '')
|
26
|
+
'class="current"' if current_page[0, path.size] == path
|
27
|
+
end
|
28
|
+
|
29
|
+
def tab(name)
|
30
|
+
dname = name.to_s.downcase
|
31
|
+
path = url_path(dname)
|
32
|
+
"<li #{class_if_current(path)}><a href='#{path.gsub(" ", "_")}'>#{name}</a></li>"
|
33
|
+
end
|
34
|
+
|
35
|
+
def tabs
|
36
|
+
Resque::Server.tabs
|
37
|
+
end
|
38
|
+
|
39
|
+
def url_prefix
|
40
|
+
Resque::Server.url_prefix
|
41
|
+
end
|
42
|
+
|
43
|
+
def redis_get_size(key)
|
44
|
+
case Resque.redis.type(key)
|
45
|
+
when 'none'
|
46
|
+
0
|
47
|
+
when 'hash'
|
48
|
+
Resque.redis.hlen(key)
|
49
|
+
when 'list'
|
50
|
+
Resque.redis.llen(key)
|
51
|
+
when 'set'
|
52
|
+
Resque.redis.scard(key)
|
53
|
+
when 'string'
|
54
|
+
Resque.redis.get(key).length
|
55
|
+
when 'zset'
|
56
|
+
Resque.redis.zcard(key)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def redis_get_value_as_array(key, start=0)
|
61
|
+
case Resque.redis.type(key)
|
62
|
+
when 'none'
|
63
|
+
[]
|
64
|
+
when 'hash'
|
65
|
+
Resque.redis.hgetall(key).to_a[start..(start + 20)]
|
66
|
+
when 'list'
|
67
|
+
Resque.redis.lrange(key, start, start + 20)
|
68
|
+
when 'set'
|
69
|
+
Resque.redis.smembers(key)[start..(start + 20)]
|
70
|
+
when 'string'
|
71
|
+
[Resque.redis.get(key)]
|
72
|
+
when 'zset'
|
73
|
+
Resque.redis.zrange(key, start, start + 20)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def show_args(args)
|
78
|
+
Array(args).map do |a|
|
79
|
+
a.to_yaml
|
80
|
+
end.join("\n")
|
81
|
+
rescue
|
82
|
+
args.to_s
|
83
|
+
end
|
84
|
+
|
85
|
+
def worker_hosts
|
86
|
+
@worker_hosts ||= worker_hosts!
|
87
|
+
end
|
88
|
+
|
89
|
+
def worker_hosts!
|
90
|
+
hosts = Hash.new { [] }
|
91
|
+
|
92
|
+
Resque.workers.each do |worker|
|
93
|
+
host, _ = worker.to_s.split(':')
|
94
|
+
hosts[host] += [worker.to_s]
|
95
|
+
end
|
96
|
+
|
97
|
+
hosts
|
98
|
+
end
|
99
|
+
|
100
|
+
def partial?
|
101
|
+
@partial
|
102
|
+
end
|
103
|
+
|
104
|
+
def partial(template, local_vars = {})
|
105
|
+
@partial = true
|
106
|
+
erb(template.to_sym, {:layout => false}, local_vars)
|
107
|
+
ensure
|
108
|
+
@partial = false
|
109
|
+
end
|
110
|
+
|
111
|
+
def poll
|
112
|
+
if defined?(@polling) && @polling
|
113
|
+
text = "Last Updated: #{Time.now.strftime("%H:%M:%S")}"
|
114
|
+
else
|
115
|
+
text = "<a href='#{u(request.path_info)}.poll' rel='poll'>Live Poll!!</a>"
|
116
|
+
end
|
117
|
+
"<p class='poll'>#{text}</p>"
|
118
|
+
end
|
119
|
+
|
120
|
+
####################
|
121
|
+
#failed.erb helpers#
|
122
|
+
####################
|
123
|
+
|
124
|
+
def failed_date_format
|
125
|
+
"%Y/%m/%d %T %z"
|
126
|
+
end
|
127
|
+
|
128
|
+
def failed_multiple_queues?
|
129
|
+
return @multiple_failed_queues if defined?(@multiple_failed_queues)
|
130
|
+
|
131
|
+
@multiple_failed_queues = Resque::Failure.queues.size > 1 ||
|
132
|
+
(defined?(Resque::Failure::RedisMultiQueue) && Resque::Failure.backend == Resque::Failure::RedisMultiQueue)
|
133
|
+
end
|
134
|
+
|
135
|
+
def failed_size
|
136
|
+
@failed_size ||= Resque::Failure.count(params[:queue], params[:class])
|
137
|
+
end
|
138
|
+
|
139
|
+
def failed_per_page
|
140
|
+
@failed_per_page = if params[:class]
|
141
|
+
failed_size
|
142
|
+
else
|
143
|
+
20
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def failed_start_at
|
148
|
+
params[:start].to_i
|
149
|
+
end
|
150
|
+
|
151
|
+
def failed_end_at
|
152
|
+
if failed_start_at + failed_per_page > failed_size
|
153
|
+
failed_size
|
154
|
+
else
|
155
|
+
failed_start_at + failed_per_page - 1
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def failed_order
|
160
|
+
params[:order] || 'desc'
|
161
|
+
end
|
162
|
+
|
163
|
+
def failed_class_counts(queue = params[:queue])
|
164
|
+
classes = Hash.new(0)
|
165
|
+
Resque::Failure.each(0, Resque::Failure.count(queue), queue) do |_, item|
|
166
|
+
class_name = item['payload']['class'] if item['payload']
|
167
|
+
class_name ||= "nil"
|
168
|
+
classes[class_name] += 1
|
169
|
+
end
|
170
|
+
classes
|
171
|
+
end
|
172
|
+
|
173
|
+
def page_entries_info(start, stop, size, name = nil)
|
174
|
+
if size == 0
|
175
|
+
name ? "No #{name}s" : '<b>0</b>'
|
176
|
+
elsif size == 1
|
177
|
+
'Showing <b>1</b>' + (name ? " #{name}" : '')
|
178
|
+
elsif size > failed_per_page
|
179
|
+
"Showing #{start}-#{stop} of <b>#{size}</b>" + (name ? " #{name}s" : '')
|
180
|
+
else
|
181
|
+
"Showing #{start} to <b>#{size - 1}</b>" + (name ? " #{name}s" : '')
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/lib/resque/stat.rb
CHANGED
@@ -35,8 +35,8 @@ module Resque
|
|
35
35
|
#
|
36
36
|
# Can optionally accept a second int parameter. The stat is then
|
37
37
|
# incremented by that amount.
|
38
|
-
def incr(stat, by = 1)
|
39
|
-
data_store.increment_stat(stat,by)
|
38
|
+
def incr(stat, by = 1, **opts)
|
39
|
+
data_store.increment_stat(stat, by, **opts)
|
40
40
|
end
|
41
41
|
|
42
42
|
# Increments a stat by one.
|
@@ -58,8 +58,8 @@ module Resque
|
|
58
58
|
end
|
59
59
|
|
60
60
|
# Removes a stat from Redis, effectively setting it to 0.
|
61
|
-
def clear(stat)
|
62
|
-
data_store.clear_stat(stat)
|
61
|
+
def clear(stat, **opts)
|
62
|
+
data_store.clear_stat(stat, **opts)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
data/lib/resque/tasks.rb
CHANGED
@@ -16,7 +16,7 @@ namespace :resque do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
worker.prepare
|
19
|
-
worker.log "Starting worker #{
|
19
|
+
worker.log "Starting worker #{worker}"
|
20
20
|
worker.work(ENV['INTERVAL'] || 5) # interval, will block
|
21
21
|
end
|
22
22
|
|
@@ -39,7 +39,7 @@ namespace :resque do
|
|
39
39
|
|
40
40
|
# Preload app files if this is Rails
|
41
41
|
task :preload => :setup do
|
42
|
-
if defined?(Rails)
|
42
|
+
if defined?(Rails) && Rails.respond_to?(:application)
|
43
43
|
if Rails.application.config.eager_load
|
44
44
|
ActiveSupport.run_load_hooks(:before_eager_load, Rails.application)
|
45
45
|
Rails.application.config.eager_load_namespaces.each(&:eager_load!)
|
data/lib/resque/version.rb
CHANGED