resque-scheduler 4.3.1 → 4.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -8,13 +8,18 @@ module Resque
8
8
  yield self
9
9
  end
10
10
 
11
+ attr_writer :environment
12
+ def environment
13
+ @environment ||= ENV
14
+ end
15
+
11
16
  # Used in `#load_schedule_job`
12
17
  attr_writer :env
13
18
 
14
19
  def env
15
20
  return @env if @env
16
21
  @env ||= Rails.env if defined?(Rails) && Rails.respond_to?(:env)
17
- @env ||= ENV['RAILS_ENV']
22
+ @env ||= environment['RAILS_ENV']
18
23
  @env
19
24
  end
20
25
 
@@ -22,42 +27,48 @@ module Resque
22
27
  attr_writer :verbose
23
28
 
24
29
  def verbose
25
- @verbose ||= !!ENV['VERBOSE']
30
+ @verbose ||= to_bool(environment['VERBOSE'])
26
31
  end
27
32
 
28
33
  # If set, produces no output
29
34
  attr_writer :quiet
30
35
 
31
36
  def quiet
32
- @quiet ||= !!ENV['QUIET']
37
+ @quiet ||= to_bool(environment['QUIET'])
33
38
  end
34
39
 
35
40
  # If set, will write messages to the file
36
41
  attr_writer :logfile
37
42
 
38
43
  def logfile
39
- @logfile ||= ENV['LOGFILE']
44
+ @logfile ||= environment['LOGFILE']
40
45
  end
41
46
 
42
- # Sets whether to log in 'text' or 'json'
47
+ # Sets whether to log in 'text', 'json' or 'logfmt'
43
48
  attr_writer :logformat
44
49
 
45
50
  def logformat
46
- @logformat ||= ENV['LOGFORMAT']
51
+ @logformat ||= environment['LOGFORMAT']
47
52
  end
48
53
 
49
54
  # If set, will try to update the schedule in the loop
50
55
  attr_writer :dynamic
51
56
 
52
57
  def dynamic
53
- @dynamic ||= !!ENV['DYNAMIC_SCHEDULE']
58
+ @dynamic ||= to_bool(environment['DYNAMIC_SCHEDULE'])
54
59
  end
55
60
 
56
61
  # If set, will append the app name to procline
57
62
  attr_writer :app_name
58
63
 
59
64
  def app_name
60
- @app_name ||= ENV['APP_NAME']
65
+ @app_name ||= environment['APP_NAME']
66
+ end
67
+
68
+ def delayed_requeue_batch_size
69
+ @delayed_requeue_batch_size ||= \
70
+ ENV['DELAYED_REQUEUE_BATCH_SIZE'].to_i if environment['DELAYED_REQUEUE_BATCH_SIZE']
71
+ @delayed_requeue_batch_size ||= 100
61
72
  end
62
73
 
63
74
  # Amount of time in seconds to sleep between polls of the delayed
@@ -66,7 +77,25 @@ module Resque
66
77
 
67
78
  def poll_sleep_amount
68
79
  @poll_sleep_amount ||=
69
- Float(ENV.fetch('RESQUE_SCHEDULER_INTERVAL', '5'))
80
+ Float(environment.fetch('RESQUE_SCHEDULER_INTERVAL', '5'))
81
+ end
82
+
83
+ private
84
+
85
+ # Copied from https://github.com/rails/rails/blob/main/activemodel/lib/active_model/type/boolean.rb#L17
86
+ TRUE_VALUES = [
87
+ true, 1,
88
+ '1', :'1',
89
+ 't', :t,
90
+ 'T', :T,
91
+ 'true', :true,
92
+ 'TRUE', :TRUE,
93
+ 'on', :on,
94
+ 'ON', :ON
95
+ ].to_set.freeze
96
+
97
+ def to_bool(value)
98
+ TRUE_VALUES.include?(value)
70
99
  end
71
100
  end
72
101
  end
@@ -24,7 +24,7 @@ module Resque
24
24
  def enqueue_at_with_queue(queue, timestamp, klass, *args)
25
25
  return false unless plugin.run_before_schedule_hooks(klass, *args)
26
26
 
27
- if Resque.inline? || timestamp.to_i < Time.now.to_i
27
+ if Resque.inline? || timestamp.to_i <= Time.now.to_i
28
28
  # Just create the job and let resque perform it right away with
29
29
  # inline. If the class is a custom job class, call self#scheduled
30
30
  # on it. This allows you to do things like
@@ -33,7 +33,7 @@ module Resque
33
33
  if klass.respond_to?(:scheduled)
34
34
  klass.scheduled(queue, klass.to_s, *args)
35
35
  else
36
- Resque::Job.create(queue, klass, *args)
36
+ Resque.enqueue_to(queue, klass, *args)
37
37
  end
38
38
  else
39
39
  delayed_push(timestamp, job_to_hash_with_queue(queue, klass, args))
@@ -45,6 +45,9 @@ module Resque
45
45
  # Identical to enqueue_at but takes number_of_seconds_from_now
46
46
  # instead of a timestamp.
47
47
  def enqueue_in(number_of_seconds_from_now, klass, *args)
48
+ unless number_of_seconds_from_now.is_a?(Numeric)
49
+ raise ArgumentError, 'Please supply a numeric number of seconds'
50
+ end
48
51
  enqueue_at(Time.now + number_of_seconds_from_now, klass, *args)
49
52
  end
50
53
 
@@ -53,20 +56,41 @@ module Resque
53
56
  # number of seconds has passed.
54
57
  def enqueue_in_with_queue(queue, number_of_seconds_from_now,
55
58
  klass, *args)
59
+ unless number_of_seconds_from_now.is_a?(Numeric)
60
+ raise ArgumentError, 'Please supply a numeric number of seconds'
61
+ end
56
62
  enqueue_at_with_queue(queue, Time.now + number_of_seconds_from_now,
57
63
  klass, *args)
58
64
  end
59
65
 
66
+ # Update the delayed timestamp of any matching delayed jobs or enqueue a
67
+ # new job if no matching jobs are found. Returns the number of delayed or
68
+ # enqueued jobs.
69
+ def delay_or_enqueue_at(timestamp, klass, *args)
70
+ count = remove_delayed(klass, *args)
71
+ count = 1 if count == 0
72
+
73
+ count.times do
74
+ enqueue_at(timestamp, klass, *args)
75
+ end
76
+ end
77
+
78
+ # Identical to +delay_or_enqueue_at+, except it takes
79
+ # number_of_seconds_from_now instead of a timestamp
80
+ def delay_or_enqueue_in(number_of_seconds_from_now, klass, *args)
81
+ delay_or_enqueue_at(Time.now + number_of_seconds_from_now, klass, *args)
82
+ end
83
+
60
84
  # Used internally to stuff the item into the schedule sorted list.
61
- # +timestamp+ can be either in seconds or a datetime object Insertion
62
- # if O(log(n)). Returns true if it's the first job to be scheduled at
63
- # that time, else false
85
+ # +timestamp+ can be either in seconds or a datetime object. The
86
+ # insertion time complexity is O(log(n)). Returns true if it's
87
+ # the first job to be scheduled at that time, else false.
64
88
  def delayed_push(timestamp, item)
65
89
  # First add this item to the list for this timestamp
66
90
  redis.rpush("delayed:#{timestamp.to_i}", encode(item))
67
91
 
68
92
  # Store the timestamps at with this item occurs
69
- redis.sadd("timestamps:#{encode(item)}", "delayed:#{timestamp.to_i}")
93
+ redis.sadd("timestamps:#{encode(item)}", ["delayed:#{timestamp.to_i}"])
70
94
 
71
95
  # Now, add this timestamp to the zsets. The score and the value are
72
96
  # the same since we'll be querying by timestamp, and we don't have
@@ -82,6 +106,7 @@ module Resque
82
106
  end
83
107
 
84
108
  # Returns the size of the delayed queue schedule
109
+ # this does not represent the number of items in the queue to be scheduled
85
110
  def delayed_queue_schedule_size
86
111
  redis.zcard :delayed_queue_schedule
87
112
  end
@@ -115,7 +140,7 @@ module Resque
115
140
  key = "delayed:#{timestamp.to_i}"
116
141
 
117
142
  encoded_item = redis.lpop(key)
118
- redis.srem("timestamps:#{encoded_item}", key)
143
+ redis.srem("timestamps:#{encoded_item}", [key])
119
144
  item = decode(encoded_item)
120
145
 
121
146
  # If the list is empty, remove it.
@@ -128,10 +153,7 @@ module Resque
128
153
  Array(redis.zrange(:delayed_queue_schedule, 0, -1)).each do |item|
129
154
  key = "delayed:#{item}"
130
155
  items = redis.lrange(key, 0, -1)
131
- redis.pipelined do
132
- items.each { |ts_item| redis.del("timestamps:#{ts_item}") }
133
- end
134
- redis.del key
156
+ redis.del(key, items.map { |ts_item| "timestamps:#{ts_item}" })
135
157
  end
136
158
 
137
159
  redis.del :delayed_queue_schedule
@@ -143,6 +165,11 @@ module Resque
143
165
  remove_delayed_job(search)
144
166
  end
145
167
 
168
+ def remove_delayed_in_queue(klass, queue, *args)
169
+ search = encode(job_to_hash_with_queue(queue, klass, args))
170
+ remove_delayed_job(search)
171
+ end
172
+
146
173
  # Given an encoded item, enqueue it now
147
174
  def enqueue_delayed(klass, *args)
148
175
  hash = job_to_hash(klass, args)
@@ -151,6 +178,13 @@ module Resque
151
178
  end
152
179
  end
153
180
 
181
+ def enqueue_delayed_with_queue(klass, queue, *args)
182
+ hash = job_to_hash_with_queue(queue, klass, args)
183
+ remove_delayed_in_queue(klass, queue, *args).times do
184
+ Resque::Scheduler.enqueue_from_config(hash)
185
+ end
186
+ end
187
+
154
188
  # Given a block, remove jobs that return true from a block
155
189
  #
156
190
  # This allows for removal of delayed jobs that have arguments matching
@@ -175,7 +209,15 @@ module Resque
175
209
  found_jobs.reduce(0) do |sum, encoded_job|
176
210
  decoded_job = decode(encoded_job)
177
211
  klass = Util.constantize(decoded_job['class'])
178
- sum + enqueue_delayed(klass, *decoded_job['args'])
212
+ queue = decoded_job['queue']
213
+
214
+ if queue
215
+ jobs_queued = enqueue_delayed_with_queue(klass, queue, *decoded_job['args'])
216
+ else
217
+ jobs_queued = enqueue_delayed(klass, *decoded_job['args'])
218
+ end
219
+
220
+ jobs_queued + sum
179
221
  end
180
222
  end
181
223
 
@@ -190,9 +232,9 @@ module Resque
190
232
 
191
233
  # Beyond 100 there's almost no improvement in speed
192
234
  found = timestamps.each_slice(100).map do |ts_group|
193
- jobs = redis.pipelined do |r|
235
+ jobs = redis.pipelined do |pipeline|
194
236
  ts_group.each do |ts|
195
- r.lrange("delayed:#{ts}", 0, -1)
237
+ pipeline.lrange("delayed:#{ts}", 0, -1)
196
238
  end
197
239
  end
198
240
 
@@ -215,7 +257,7 @@ module Resque
215
257
  key = "delayed:#{timestamp.to_i}"
216
258
  encoded_job = encode(job_to_hash(klass, args))
217
259
 
218
- redis.srem("timestamps:#{encoded_job}", key)
260
+ redis.srem("timestamps:#{encoded_job}", [key])
219
261
  count = redis.lrem(key, 0, encoded_job)
220
262
  clean_up_timestamp(key, timestamp)
221
263
 
@@ -255,6 +297,22 @@ module Resque
255
297
  redis.hget('delayed:last_enqueued_at', job_name)
256
298
  end
257
299
 
300
+ def clean_up_timestamp(key, timestamp)
301
+ # Use a watch here to ensure nobody adds jobs to this delayed
302
+ # queue while we're removing it.
303
+ redis.watch(key) do
304
+ if redis.llen(key).to_i == 0
305
+ # If the list is empty, remove it.
306
+ redis.multi do |transaction|
307
+ transaction.del(key)
308
+ transaction.zrem(:delayed_queue_schedule, timestamp.to_i)
309
+ end
310
+ else
311
+ redis.redis.unwatch
312
+ end
313
+ end
314
+ end
315
+
258
316
  private
259
317
 
260
318
  def job_to_hash(klass, args)
@@ -265,38 +323,27 @@ module Resque
265
323
  { class: klass.to_s, args: args, queue: queue }
266
324
  end
267
325
 
326
+ # Removes a job from the queue, but not modify the timestamp schedule. This method
327
+ # will not effect the output of `delayed_queue_schedule_size`
268
328
  def remove_delayed_job(encoded_job)
269
329
  return 0 if Resque.inline?
270
330
 
271
331
  timestamps = redis.smembers("timestamps:#{encoded_job}")
272
332
 
273
- replies = redis.pipelined do
333
+ replies = redis.pipelined do |pipeline|
274
334
  timestamps.each do |key|
275
- redis.lrem(key, 0, encoded_job)
276
- redis.srem("timestamps:#{encoded_job}", key)
335
+ pipeline.lrem(key, 0, encoded_job)
336
+ pipeline.srem("timestamps:#{encoded_job}", [key])
277
337
  end
278
338
  end
279
339
 
340
+ # timestamp key is not removed from the schedule, this is done later
341
+ # by the scheduler loop
342
+
280
343
  return 0 if replies.nil? || replies.empty?
281
344
  replies.each_slice(2).map(&:first).inject(:+)
282
345
  end
283
346
 
284
- def clean_up_timestamp(key, timestamp)
285
- # Use a watch here to ensure nobody adds jobs to this delayed
286
- # queue while we're removing it.
287
- redis.watch(key) do
288
- if redis.llen(key).to_i == 0
289
- # If the list is empty, remove it.
290
- redis.multi do
291
- redis.del(key)
292
- redis.zrem(:delayed_queue_schedule, timestamp.to_i)
293
- end
294
- else
295
- redis.redis.unwatch
296
- end
297
- end
298
- end
299
-
300
347
  def search_first_delayed_timestamp_in_range(start_at, stop_at)
301
348
  start_at = start_at.nil? ? '-inf' : start_at.to_i
302
349
  stop_at = stop_at.nil? ? '+inf' : stop_at.to_i
@@ -38,12 +38,8 @@ module Resque
38
38
  true
39
39
  end
40
40
 
41
- unless Process.respond_to?('daemon')
42
- abort 'background option is set, which requires ruby >= 1.9'
43
- end
44
-
45
41
  Process.daemon(true, !Resque::Scheduler.quiet)
46
- Resque.redis.client.reconnect
42
+ Resque.redis.reconnect
47
43
  end
48
44
 
49
45
  def setup_pid_file
@@ -64,13 +60,13 @@ module Resque
64
60
 
65
61
  c.dynamic = !!options[:dynamic] if options.key?(:dynamic)
66
62
 
67
- c.env = options[:env] if options.key(:env)
63
+ c.env = options[:env] if options.key?(:env)
68
64
 
69
65
  c.logfile = options[:logfile] if options.key?(:logfile)
70
66
 
71
67
  c.logformat = options[:logformat] if options.key?(:logformat)
72
68
 
73
- if psleep = options[:poll_sleep_amount] && !psleep.nil?
69
+ if (psleep = options[:poll_sleep_amount]) && !psleep.nil?
74
70
  c.poll_sleep_amount = Float(psleep)
75
71
  end
76
72
 
@@ -47,7 +47,7 @@ module Resque
47
47
 
48
48
  def hostname
49
49
  local_hostname = Socket.gethostname
50
- Socket.gethostbyname(local_hostname).first
50
+ Addrinfo.getaddrinfo(local_hostname, 'http').first.getnameinfo.first
51
51
  rescue
52
52
  local_hostname
53
53
  end
@@ -43,7 +43,7 @@ module Resque
43
43
  @locked_sha = nil if refresh
44
44
 
45
45
  @locked_sha ||=
46
- Resque.redis.script(:load, <<-EOF.gsub(/^ {14}/, ''))
46
+ Resque.data_store.redis.script(:load, <<-EOF.gsub(/^ {14}/, ''))
47
47
  if redis.call('GET', KEYS[1]) == ARGV[1]
48
48
  then
49
49
  redis.call('EXPIRE', KEYS[1], #{timeout})
@@ -62,7 +62,7 @@ module Resque
62
62
  @acquire_sha = nil if refresh
63
63
 
64
64
  @acquire_sha ||=
65
- Resque.redis.script(:load, <<-EOF.gsub(/^ {14}/, ''))
65
+ Resque.data_store.redis.script(:load, <<-EOF.gsub(/^ {14}/, ''))
66
66
  if redis.call('SETNX', KEYS[1], ARGV[1]) == 1
67
67
  then
68
68
  redis.call('EXPIRE', KEYS[1], #{timeout})
@@ -2,7 +2,7 @@
2
2
 
3
3
  # ### Locking the scheduler process
4
4
  #
5
- # There are two places in resque-scheduler that need to be synchonized in order
5
+ # There are two places in resque-scheduler that need to be synchronized in order
6
6
  # to be able to run redundant scheduler processes while ensuring jobs don't get
7
7
  # queued multiple times when the master process changes.
8
8
  #
@@ -76,7 +76,7 @@ module Resque
76
76
 
77
77
  def release_master_lock
78
78
  master_lock.release
79
- rescue Errno::EAGAIN, Errno::ECONNRESET, Redis::CannotConnectError
79
+ rescue *INTERMITTENT_ERRORS
80
80
  @master_lock = nil
81
81
  end
82
82
 
@@ -97,7 +97,7 @@ module Resque
97
97
  end
98
98
 
99
99
  def redis_master_version
100
- Resque.redis.info['redis_version'].to_f
100
+ Resque.data_store.redis.info['redis_version'].to_f
101
101
  end
102
102
  end
103
103
  end
@@ -15,7 +15,7 @@ module Resque
15
15
  # - :quiet if logger needs to be silent for all levels. Default - false
16
16
  # - :verbose if there is a need in debug messages. Default - false
17
17
  # - :log_dev to output logs into a desired file. Default - STDOUT
18
- # - :format log format, either 'text' or 'json'. Default - 'text'
18
+ # - :format log format, either 'text', 'json' or 'logfmt'. Default - 'text'
19
19
  #
20
20
  # Example:
21
21
  #
@@ -32,6 +32,7 @@ module Resque
32
32
  # Returns an instance of MonoLogger
33
33
  def build
34
34
  logger = MonoLogger.new(@log_dev)
35
+ logger.progname = 'resque-scheduler'.freeze
35
36
  logger.level = level
36
37
  logger.formatter = send(:"#{@format}_formatter")
37
38
  logger
@@ -50,21 +51,31 @@ module Resque
50
51
  end
51
52
 
52
53
  def text_formatter
53
- proc do |severity, datetime, _progname, msg|
54
- "resque-scheduler: [#{severity}] #{datetime.iso8601}: #{msg}\n"
54
+ proc do |severity, datetime, progname, msg|
55
+ "#{progname}: [#{severity}] #{datetime.iso8601}: #{msg}\n"
55
56
  end
56
57
  end
57
58
 
58
59
  def json_formatter
59
60
  proc do |severity, datetime, progname, msg|
60
61
  require 'json'
61
- JSON.dump(
62
- name: 'resque-scheduler',
62
+ log_data = {
63
+ name: progname,
63
64
  progname: progname,
64
65
  level: severity,
65
66
  timestamp: datetime.iso8601,
66
67
  msg: msg
67
- ) + "\n"
68
+ }
69
+ JSON.dump(log_data) + "\n"
70
+ end
71
+ end
72
+
73
+ def logfmt_formatter
74
+ proc do |severity, datetime, progname, msg|
75
+ "timestamp=\"#{datetime.iso8601}\" " \
76
+ "level=\"#{severity}\" " \
77
+ "progname=\"#{progname}\" " \
78
+ "msg=\"#{msg}\"\n"
68
79
  end
69
80
  end
70
81
  end
@@ -36,7 +36,7 @@ module Resque
36
36
  # :args can be any yaml which will be converted to a ruby literal and
37
37
  # passed in a params. (optional)
38
38
  #
39
- # :rails_envs is the list of envs where the job gets loaded. Envs are
39
+ # :rails_env is the list of envs where the job gets loaded. Envs are
40
40
  # comma separated (optional)
41
41
  #
42
42
  # :description is just that, a description of the job (optional). If
@@ -91,7 +91,7 @@ module Resque
91
91
  non_persistent_schedules[name] = decode(encode(config))
92
92
  end
93
93
 
94
- redis.sadd(:schedules_changed, name)
94
+ redis.sadd(:schedules_changed, [name])
95
95
  reload_schedule! if reload
96
96
  end
97
97
 
@@ -101,12 +101,13 @@ module Resque
101
101
  end
102
102
 
103
103
  # remove a given schedule by name
104
- def remove_schedule(name)
104
+ # Preventing a reload is optional and available to batch operations
105
+ def remove_schedule(name, reload = true)
105
106
  non_persistent_schedules.delete(name)
106
107
  redis.hdel(:persistent_schedules, name)
107
- redis.sadd(:schedules_changed, name)
108
+ redis.sadd(:schedules_changed, [name])
108
109
 
109
- reload_schedule!
110
+ reload_schedule! if reload
110
111
  end
111
112
 
112
113
  private
@@ -1,9 +1,9 @@
1
1
  <h1>Delayed Jobs</h1>
2
- <%- size = resque.delayed_queue_schedule_size %>
2
+ <% size = resque.delayed_queue_schedule_size %>
3
3
 
4
4
  <%= scheduler_view :search_form, layout: false %>
5
5
 
6
- <p style="font-color: red; font-weight: bold;">
6
+ <p style="color: red; font-weight: bold;">
7
7
  <%= @error_message %>
8
8
  </p>
9
9
 
@@ -16,6 +16,14 @@
16
16
  Showing <%= start = params[:start].to_i %> to <%= start + 20 %> of <b><%= size %></b> timestamps
17
17
  </p>
18
18
 
19
+ <% if size > 0 %>
20
+ <div style="padding-bottom: 10px">
21
+ <form method="POST" action="<%= u 'delayed/clear' %>" class='clear-delayed confirmSubmission'>
22
+ <input type='submit' name='' value='Clear Delayed Jobs' />
23
+ </form>
24
+ </div>
25
+ <% end %>
26
+
19
27
  <table>
20
28
  <tr>
21
29
  <th></th>
@@ -27,7 +35,7 @@
27
35
  </tr>
28
36
  <% resque.delayed_queue_peek(start, 20).each do |timestamp| %>
29
37
  <tr>
30
- <td>
38
+ <td style="padding-top: 12px; padding-bottom: 2px; width: 10px">
31
39
  <form action="<%= u "/delayed/queue_now" %>" method="post">
32
40
  <input type="hidden" name="timestamp" value="<%= timestamp.to_i %>">
33
41
  <input type="submit" value="Queue now">
@@ -46,18 +54,11 @@
46
54
  <td><%= h(show_job_arguments(job['args'])) if job && delayed_timestamp_size == 1 %></td>
47
55
  <td>
48
56
  <% if job %>
49
- <a href="<%=u URI("/delayed/jobs/#{job['class']}?args=" + URI.encode(job['args'].to_json)) %>">All schedules</a>
57
+ <a href="<%= u URI("/delayed/jobs/#{CGI.escape(job['class'])}?args=" + CGI.escape(job['args'].to_json)) %>">All schedules</a>
50
58
  <% end %>
51
59
  </td>
52
60
  </tr>
53
61
  <% end %>
54
62
  </table>
55
63
 
56
- <% if size > 0 %>
57
- <br>
58
- <form method="POST" action="<%=u 'delayed/clear'%>" class='clear-delayed'>
59
- <input type='submit' name='' value='Clear Delayed Jobs' />
60
- </form>
61
- <% end %>
62
-
63
64
  <%= partial :next_more, :start => start, :size => size %>
@@ -1,4 +1,4 @@
1
- <h1>Delayed jobs scheduled for <%= params[:klass] %> (<%= show_job_arguments(@args) %>)</h1>
1
+ <h1>Delayed jobs scheduled for <%=h params[:klass] %> (<%=h show_job_arguments(@args) %>)</h1>
2
2
 
3
3
  <table class='jobs'>
4
4
  <tr>
@@ -13,7 +13,7 @@
13
13
  <% jobs.each do |job| %>
14
14
  <tr>
15
15
  <td class='class'><%= job['class'] %></td>
16
- <td class='args'><%=h show_job_arguments(job['args']) %></td>
16
+ <td class='args'><%= h show_job_arguments(job['args']) %></td>
17
17
  </tr>
18
18
  <% end %>
19
19
  <% if jobs.empty? %>
@@ -8,7 +8,7 @@
8
8
  <br/> Current master: <%= Resque.redis.get(Resque::Scheduler.master_lock.key) %>
9
9
  </p>
10
10
  <p class='intro'>
11
- The highlighted jobs are skipped for current environment.
11
+ The highlighted jobs are skipped for current environment.
12
12
  </p>
13
13
  <div style="overflow-y: auto; width:100%; padding: 0px 5px;">
14
14
  <table>
@@ -29,7 +29,7 @@
29
29
  <% Resque.schedule.keys.sort.each_with_index do |name, index| %>
30
30
  <% config = Resque.schedule[name] %>
31
31
  <tr style="<%= scheduled_in_this_env?(name) ? '' : 'color: #9F6000;background: #FEEFB3;' %>">
32
- <td style="padding-left: 15px;"><%= index+ 1 %>.</td>
32
+ <td style="padding-left: 15px;"><%= index + 1 %>.</td>
33
33
  <% if Resque::Scheduler.dynamic %>
34
34
  <td style="padding-top: 12px; padding-bottom: 2px; width: 10px">
35
35
  <form action="<%= u "/schedule" %>" method="post" style="margin-left: 0">
@@ -13,13 +13,13 @@
13
13
  </tr>
14
14
  <% delayed.each do |job| %>
15
15
  <tr>
16
- <td>
16
+ <td style="padding-top: 12px; padding-bottom: 2px; width: 10px">
17
17
  <form action="<%= u "/delayed/queue_now" %>" method="post">
18
18
  <input type="hidden" name="timestamp" value="<%= job['timestamp'].to_i %>">
19
19
  <input type="submit" value="Queue now">
20
20
  </form>
21
21
  </td>
22
- <td>
22
+ <td style="padding-top: 12px; padding-bottom: 2px; width: 10px">
23
23
  <form action="<%= u "/delayed/cancel_now" %>" method="post">
24
24
  <input type="hidden" name="timestamp" value="<%= job['timestamp'].to_i %>">
25
25
  <input type="hidden" name="klass" value="<%= job['class'] %>">
@@ -33,7 +33,6 @@
33
33
  </tr>
34
34
  <% end %>
35
35
  </table>
36
- </h1>
37
36
 
38
37
  <% queued = @jobs.select { |j| j['where_at'] == 'queued' } %>
39
38
  <h1>Queued jobs</h1>
@@ -68,5 +67,3 @@
68
67
  </tr>
69
68
  <% end %>
70
69
  </table>
71
-
72
-
@@ -1,8 +1,4 @@
1
1
  <form method="POST" action="<%= u 'delayed/search' %>">
2
- <input type='input' name='search' value="<%= params[:search] %>"/>
2
+ <input type='input' name='search' value="<%= h params[:search] %>"/>
3
3
  <input type='submit' value='Search'/>
4
4
  </form>
5
-
6
-
7
-
8
-
@@ -87,7 +87,7 @@ module Resque
87
87
  def delayed_jobs_klass
88
88
  begin
89
89
  klass = Resque::Scheduler::Util.constantize(params[:klass])
90
- @args = JSON.load(URI.decode(params[:args]))
90
+ @args = JSON.load(CGI.unescape(params[:args]))
91
91
  @timestamps = Resque.scheduled_at(klass, *@args)
92
92
  rescue
93
93
  @timestamps = []
@@ -10,13 +10,13 @@ module Resque
10
10
  end
11
11
 
12
12
  # For all signals, set the shutdown flag and wait for current
13
- # poll/enqueing to finish (should be almost instant). In the
13
+ # poll/enqueuing to finish (should be almost instant). In the
14
14
  # case of sleeping, exit immediately.
15
15
  def register_signal_handlers
16
16
  (Signal.list.keys & %w(INT TERM USR1 USR2 QUIT)).each do |sig|
17
17
  trap(sig) do
18
18
  signal_queue << sig
19
- # break sleep in the primary scheduler thread, alowing
19
+ # break sleep in the primary scheduler thread, allowing
20
20
  # the signal queue to get processed as soon as possible.
21
21
  @th.wakeup if @th && @th.alive?
22
22
  end