resque-scheduler 2.3.1 → 2.4.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.

Potentially problematic release.


This version of resque-scheduler might be problematic. Click here for more details.

Files changed (49) hide show
  1. data/.gitignore +3 -0
  2. data/.rubocop.yml +11 -11
  3. data/.simplecov +1 -0
  4. data/.travis.yml +5 -2
  5. data/AUTHORS.md +3 -0
  6. data/HISTORY.md +26 -2
  7. data/LICENSE +1 -1
  8. data/README.md +120 -31
  9. data/ROADMAP.md +10 -0
  10. data/Rakefile +7 -19
  11. data/bin/resque-scheduler +5 -0
  12. data/examples/Rakefile +2 -0
  13. data/examples/config/initializers/resque-web.rb +37 -0
  14. data/examples/dynamic-scheduling/README.md +28 -0
  15. data/examples/dynamic-scheduling/app/jobs/fix_schedules_job.rb +54 -0
  16. data/examples/dynamic-scheduling/app/jobs/send_email_job.rb +9 -0
  17. data/examples/dynamic-scheduling/app/models/user.rb +16 -0
  18. data/examples/dynamic-scheduling/config/resque.yml +4 -0
  19. data/examples/dynamic-scheduling/config/static_schedule.yml +7 -0
  20. data/examples/dynamic-scheduling/lib/tasks/resque.rake +48 -0
  21. data/examples/run-resque-web +3 -0
  22. data/lib/resque-scheduler.rb +2 -0
  23. data/lib/resque/scheduler.rb +130 -41
  24. data/lib/resque/scheduler/lock/resilient.rb +1 -1
  25. data/lib/resque/scheduler_locking.rb +3 -1
  26. data/lib/resque_scheduler.rb +73 -31
  27. data/lib/resque_scheduler/cli.rb +160 -0
  28. data/lib/resque_scheduler/logger_builder.rb +27 -8
  29. data/lib/resque_scheduler/plugin.rb +10 -7
  30. data/lib/resque_scheduler/server.rb +52 -11
  31. data/lib/resque_scheduler/server/views/delayed.erb +2 -0
  32. data/lib/resque_scheduler/server/views/delayed_schedules.erb +20 -0
  33. data/lib/resque_scheduler/server/views/scheduler.erb +4 -12
  34. data/lib/resque_scheduler/tasks.rb +15 -27
  35. data/lib/resque_scheduler/version.rb +1 -1
  36. data/resque-scheduler.gemspec +2 -0
  37. data/test/cli_test.rb +286 -0
  38. data/test/delayed_queue_test.rb +70 -1
  39. data/test/resque-web_test.rb +36 -1
  40. data/test/scheduler_args_test.rb +51 -17
  41. data/test/scheduler_hooks_test.rb +1 -1
  42. data/test/scheduler_locking_test.rb +63 -1
  43. data/test/scheduler_setup_test.rb +54 -18
  44. data/test/scheduler_task_test.rb +35 -0
  45. data/test/scheduler_test.rb +130 -42
  46. data/test/support/redis_instance.rb +8 -3
  47. data/test/test_helper.rb +47 -20
  48. metadata +77 -6
  49. checksums.yaml +0 -15
@@ -22,6 +22,7 @@
22
22
  <th>Job count</th>
23
23
  <th>Class</th>
24
24
  <th>Args</th>
25
+ <th>All schedules</th>
25
26
  </tr>
26
27
  <% resque.delayed_queue_peek(start, 20).each do |timestamp| %>
27
28
  <tr>
@@ -42,6 +43,7 @@
42
43
  <% end %>
43
44
  </td>
44
45
  <td><%= h(job['args'].inspect) if job && delayed_timestamp_size == 1 %></td>
46
+ <td><a href="<%=u URI("/delayed/jobs/#{job['class']}?args=" + URI.encode(job['args'].to_json)) %>">All schedules</a></td>
45
47
  </tr>
46
48
  <% end %>
47
49
  </table>
@@ -0,0 +1,20 @@
1
+ <h1>Delayed jobs scheduled for <%= params[:klass] %> (<%= @args %>)</h1>
2
+
3
+ <table class='jobs'>
4
+ <tr>
5
+ <th>Timestamp</th>
6
+ </tr>
7
+
8
+ <% @timestamps.each do |t| %>
9
+ <tr>
10
+ <td>
11
+ <%= Time.at(t) %>
12
+ </td>
13
+ </tr>
14
+ <% end %>
15
+ <% if @timestamps.empty? %>
16
+ <tr>
17
+ <td class='no-data'>There are no such jobs scheduled.</td>
18
+ </tr>
19
+ <% end %>
20
+ </table>
@@ -19,24 +19,16 @@
19
19
  <% Resque.schedule.keys.sort.each do |name| %>
20
20
  <% config = Resque.schedule[name] %>
21
21
  <tr>
22
- <td>
23
- <form action="<%= u "/schedule/requeue" %>" method="post">
22
+ <td style="padding-top: 12px; padding-bottom: 2px; width: 10px">
23
+ <form action="<%= u "/schedule/requeue" %>" method="post" style="margin-left: 0">
24
24
  <input type="hidden" name="job_name" value="<%= h name %>">
25
25
  <input type="submit" value="Queue now">
26
26
  </form>
27
27
  </td>
28
28
  <td><%= h name %></td>
29
29
  <td><%= h config['description'] %></td>
30
- <td style="white-space:nowrap"><%= if !config['every'].nil?
31
- h('every: ' + (config['every'].is_a?(Array) ? config['every'].join(", ") : config['every'].to_s ))
32
- elsif !config['cron'].nil?
33
- h('cron: ' + config['cron'].to_s)
34
- else
35
- 'Not currently scheduled'
36
- end %></td>
37
- <td><%= (config['class'].nil? && !config['custom_job_class'].nil?) ?
38
- h(config['custom_job_class']) :
39
- h(config['class']) %></td>
30
+ <td style="white-space:nowrap"><%= h schedule_interval(config) %></td>
31
+ <td><%= h schedule_class(config) %></td>
40
32
  <td><%= h config['queue'] || queue_from_class_name(config['class']) %></td>
41
33
  <td><%= h config['args'].inspect %></td>
42
34
  </tr>
@@ -1,40 +1,28 @@
1
+ # vim:fileencoding=utf-8
2
+
3
+ require 'English'
1
4
  require 'resque/tasks'
2
- # will give you the resque tasks
5
+ require 'resque_scheduler'
3
6
 
4
7
  namespace :resque do
5
8
  task :setup
6
9
 
7
- desc "Start Resque Scheduler"
8
- task :scheduler => :scheduler_setup do
9
- require 'resque'
10
- require 'resque_scheduler'
11
-
12
- # Need to set this here for conditional Process.daemon redirect of stderr/stdout to /dev/null
13
- Resque::Scheduler.mute = true if ENV['MUTE']
14
-
15
- if ENV['BACKGROUND']
16
- unless Process.respond_to?('daemon')
17
- abort "env var BACKGROUND is set, which requires ruby >= 1.9"
18
- end
19
- Process.daemon(true, !Resque::Scheduler.mute)
20
- Resque.redis.client.reconnect
21
- end
22
-
23
- File.open(ENV['PIDFILE'], 'w') { |f| f << Process.pid.to_s } if ENV['PIDFILE']
10
+ def scheduler_cli
11
+ @scheduler_cli ||= ResqueScheduler::Cli.new(
12
+ %W(#{ENV['RESQUE_SCHEDULER_OPTIONS']})
13
+ )
14
+ end
24
15
 
25
- Resque::Scheduler.dynamic = true if ENV['DYNAMIC_SCHEDULE']
26
- Resque::Scheduler.verbose = true if ENV['VERBOSE']
27
- Resque::Scheduler.logfile = ENV['LOGFILE'] if ENV['LOGFILE']
28
- Resque::Scheduler.poll_sleep_amount = Float(ENV['RESQUE_SCHEDULER_INTERVAL']) if ENV['RESQUE_SCHEDULER_INTERVAL']
29
- Resque::Scheduler.run
16
+ desc 'Start Resque Scheduler'
17
+ task scheduler: :scheduler_setup do
18
+ scheduler_cli.setup_env
19
+ scheduler_cli.run_forever
30
20
  end
31
21
 
32
22
  task :scheduler_setup do
33
- if ENV['INITIALIZER_PATH']
34
- load ENV['INITIALIZER_PATH'].to_s.strip
35
- else
23
+ scheduler_cli.parse_options
24
+ unless scheduler_cli.pre_setup
36
25
  Rake::Task['resque:setup'].invoke
37
26
  end
38
27
  end
39
-
40
28
  end
@@ -1,5 +1,5 @@
1
1
  # vim:fileencoding=utf-8
2
2
 
3
3
  module ResqueScheduler
4
- VERSION = '2.3.1'
4
+ VERSION = '2.4.0'
5
5
  end
@@ -22,10 +22,12 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_development_dependency 'bundler', '~> 1.3'
24
24
  spec.add_development_dependency 'mocha'
25
+ spec.add_development_dependency 'pry'
25
26
  spec.add_development_dependency 'rack-test'
26
27
  spec.add_development_dependency 'rake'
27
28
  spec.add_development_dependency 'json' if RUBY_VERSION < '1.9'
28
29
  spec.add_development_dependency 'rubocop' unless RUBY_VERSION < '1.9'
30
+ spec.add_development_dependency 'simplecov' unless RUBY_VERSION < '1.9'
29
31
 
30
32
  spec.add_runtime_dependency 'redis', '>= 3.0.0'
31
33
  spec.add_runtime_dependency 'resque', '~> 1.25'
@@ -0,0 +1,286 @@
1
+ require_relative 'test_helper'
2
+
3
+ context 'Cli' do
4
+ def new_cli(argv = [], env = {})
5
+ ResqueScheduler::Cli.new(argv, env)
6
+ end
7
+
8
+ test 'does not require any positional arguments' do
9
+ assert(!new_cli.nil?)
10
+ end
11
+
12
+ test 'initializes verbose from the env' do
13
+ cli = new_cli([], { 'VERBOSE' => 'foo' })
14
+ assert_equal('foo', cli.send(:options)[:verbose])
15
+ end
16
+
17
+ test 'defaults to non-verbose' do
18
+ assert_equal(false, !!new_cli.send(:options)[:verbose])
19
+ end
20
+
21
+ test 'accepts verbose via -v' do
22
+ cli = new_cli(%w(-v))
23
+ cli.parse_options
24
+ assert_equal(true, cli.send(:options)[:verbose])
25
+ end
26
+
27
+ test 'accepts verbose via --verbose' do
28
+ cli = new_cli(%w(--verbose))
29
+ cli.parse_options
30
+ assert_equal(true, cli.send(:options)[:verbose])
31
+ end
32
+
33
+ test 'initializes background from the env' do
34
+ cli = new_cli([], { 'BACKGROUND' => '1' })
35
+ assert_equal('1', cli.send(:options)[:background])
36
+ end
37
+
38
+ test 'defaults to background=false' do
39
+ assert_equal(false, !!new_cli.send(:options)[:background])
40
+ end
41
+
42
+ test 'accepts background via -B' do
43
+ cli = new_cli(%w(-B))
44
+ cli.parse_options
45
+ assert_equal(true, cli.send(:options)[:background])
46
+ end
47
+
48
+ test 'accepts background via --background' do
49
+ cli = new_cli(%w(--background))
50
+ cli.parse_options
51
+ assert_equal(true, cli.send(:options)[:background])
52
+ end
53
+
54
+ test 'daemonizes when background is true' do
55
+ Process.expects(:daemon)
56
+ cli = new_cli(%w(--background))
57
+ cli.pre_run
58
+ end
59
+
60
+ test 'reconnects redis when background is true' do
61
+ Process.stubs(:daemon)
62
+ mock_redis_client = mock('redis_client')
63
+ mock_redis = mock('redis')
64
+ mock_redis.expects(:client).returns(mock_redis_client)
65
+ mock_redis_client.expects(:reconnect)
66
+ Resque.expects(:redis).returns(mock_redis)
67
+ cli = new_cli(%w(--background))
68
+ cli.pre_run
69
+ end
70
+
71
+ test 'aborts when background is given and Process does not support daemon' do
72
+ Process.stubs(:daemon)
73
+ Process.expects(:respond_to?).with('daemon').returns(false)
74
+ cli = new_cli(%w(--background))
75
+ cli.expects(:abort)
76
+ cli.pre_run
77
+ end
78
+
79
+ test 'initializes pidfile from the env' do
80
+ cli = new_cli([], { 'PIDFILE' => 'bar' })
81
+ assert_equal('bar', cli.send(:options)[:pidfile])
82
+ end
83
+
84
+ test 'defaults to nil pidfile' do
85
+ assert_equal(nil, new_cli.send(:options)[:pidfile])
86
+ end
87
+
88
+ test 'accepts pidfile via -P' do
89
+ cli = new_cli(%w(-P foo))
90
+ cli.parse_options
91
+ assert_equal('foo', cli.send(:options)[:pidfile])
92
+ end
93
+
94
+ test 'accepts pidfile via --pidfile' do
95
+ cli = new_cli(%w(--pidfile foo))
96
+ cli.parse_options
97
+ assert_equal('foo', cli.send(:options)[:pidfile])
98
+ end
99
+
100
+ test 'writes pid to pidfile when given' do
101
+ mock_pidfile = mock('pidfile')
102
+ mock_pidfile.expects(:puts)
103
+ File.expects(:open).with('derp.pid', 'w').yields(mock_pidfile)
104
+ cli = new_cli(%w(--pidfile derp.pid))
105
+ cli.pre_run
106
+ end
107
+
108
+ test 'initializes dynamic from the env' do
109
+ cli = new_cli([], { 'DYNAMIC_SCHEDULE' => '1' })
110
+ assert_equal('flurb', cli.send(:options)[:dynamic])
111
+ end
112
+
113
+ test 'defaults to nil dynamic' do
114
+ assert_equal(nil, new_cli.send(:options)[:dynamic])
115
+ end
116
+
117
+ test 'accepts dynamic via -D' do
118
+ cli = new_cli(%w(-D))
119
+ cli.parse_options
120
+ assert_equal(true, cli.send(:options)[:dynamic])
121
+ end
122
+
123
+ test 'accepts dynamic via --dynamic-schedule' do
124
+ cli = new_cli(%w(--dynamic-schedule))
125
+ cli.parse_options
126
+ assert_equal(true, cli.send(:options)[:dynamic])
127
+ end
128
+
129
+ test 'initializes env from the env' do
130
+ cli = new_cli([], { 'RAILS_ENV' => 'flurb' })
131
+ assert_equal('flurb', cli.send(:options)[:env])
132
+ end
133
+
134
+ test 'defaults to nil env' do
135
+ assert_equal(nil, new_cli.send(:options)[:env])
136
+ end
137
+
138
+ test 'accepts env via -E' do
139
+ cli = new_cli(%w(-E bork))
140
+ cli.parse_options
141
+ assert_equal('bork', cli.send(:options)[:env])
142
+ end
143
+
144
+ test 'accepts env via --environment' do
145
+ cli = new_cli(%w(--environment hork))
146
+ cli.parse_options
147
+ assert_equal('hork', cli.send(:options)[:env])
148
+ end
149
+
150
+ test 'initializes initializer_path from the env' do
151
+ cli = new_cli([], { 'INITIALIZER_PATH' => 'herp.rb' })
152
+ assert_equal('herp.rb', cli.send(:options)[:initializer_path])
153
+ end
154
+
155
+ test 'defaults to nil initializer_path' do
156
+ assert_equal(nil, new_cli.send(:options)[:initializer_path])
157
+ end
158
+
159
+ test 'accepts initializer_path via -I' do
160
+ cli = new_cli(%w(-I hambone.rb))
161
+ cli.parse_options
162
+ assert_equal('hambone.rb', cli.send(:options)[:initializer_path])
163
+ end
164
+
165
+ test 'accepts initializer_path via --initalizer-path' do
166
+ cli = new_cli(%w(--initializer-path cookies.rb))
167
+ cli.parse_options
168
+ assert_equal('cookies.rb', cli.send(:options)[:initializer_path])
169
+ end
170
+
171
+ test 'loads given initilalizer_path' do
172
+ cli = new_cli(%w(--initializer-path fuzzbert.rb))
173
+ cli.expects(:load).with('fuzzbert.rb')
174
+ cli.pre_run
175
+ end
176
+
177
+ test 'initializes mute/quiet from the env' do
178
+ cli = new_cli([], { 'QUIET' => '1' })
179
+ assert_equal('1', cli.send(:options)[:mute])
180
+ end
181
+
182
+ test 'defaults to unmuted' do
183
+ assert_equal(false, !!new_cli.send(:options)[:mute])
184
+ end
185
+
186
+ test 'accepts mute/quiet via -q' do
187
+ cli = new_cli(%w(-q))
188
+ cli.parse_options
189
+ assert_equal(true, cli.send(:options)[:mute])
190
+ end
191
+
192
+ test 'accepts mute via --quiet' do
193
+ cli = new_cli(%w(--quiet))
194
+ cli.parse_options
195
+ assert_equal(true, cli.send(:options)[:mute])
196
+ end
197
+
198
+ test 'initializes logfile from the env' do
199
+ cli = new_cli([], { 'LOGFILE' => 'derp.log' })
200
+ assert_equal('derp.log', cli.send(:options)[:logfile])
201
+ end
202
+
203
+ test 'defaults to nil logfile' do
204
+ assert_equal(nil, new_cli.send(:options)[:logfile])
205
+ end
206
+
207
+ test 'accepts logfile via -l' do
208
+ cli = new_cli(%w(-l hurm.out))
209
+ cli.parse_options
210
+ assert_equal('hurm.out', cli.send(:options)[:logfile])
211
+ end
212
+
213
+ test 'accepts logfile via --logfile' do
214
+ cli = new_cli(%w(--logfile flam.log))
215
+ cli.parse_options
216
+ assert_equal('flam.log', cli.send(:options)[:logfile])
217
+ end
218
+
219
+ test 'initializes logformat from the env' do
220
+ cli = new_cli([], { 'LOGFORMAT' => 'fancy' })
221
+ assert_equal('fancy', cli.send(:options)[:logformat])
222
+ end
223
+
224
+ test 'defaults to nil logformat' do
225
+ assert_equal(nil, new_cli.send(:options)[:logformat])
226
+ end
227
+
228
+ test 'accepts logformat via -F' do
229
+ cli = new_cli(%w(-F silly))
230
+ cli.parse_options
231
+ assert_equal('silly', cli.send(:options)[:logformat])
232
+ end
233
+
234
+ test 'accepts logformat via --logformat' do
235
+ cli = new_cli(%w(--logformat flimsy))
236
+ cli.parse_options
237
+ assert_equal('flimsy', cli.send(:options)[:logformat])
238
+ end
239
+
240
+ test 'initializes dynamic from the env' do
241
+ cli = new_cli([], { 'DYNAMIC_SCHEDULE' => '1' })
242
+ assert_equal('1', cli.send(:options)[:dynamic])
243
+ end
244
+
245
+ test 'defaults to dynamic=false' do
246
+ assert_equal(false, !!new_cli.send(:options)[:dynamic])
247
+ end
248
+
249
+ test 'accepts dynamic via -D' do
250
+ cli = new_cli(%w(-D))
251
+ cli.parse_options
252
+ assert_equal(true, cli.send(:options)[:dynamic])
253
+ end
254
+
255
+ test 'accepts dynamic via --dynamic-schedule' do
256
+ cli = new_cli(%w(--dynamic-schedule))
257
+ cli.parse_options
258
+ assert_equal(true, cli.send(:options)[:dynamic])
259
+ end
260
+
261
+ test 'initializes app_name from the env' do
262
+ cli = new_cli([], { 'APP_NAME' => 'sprocket' })
263
+ assert_equal('sprocket', cli.send(:options)[:app_name])
264
+ end
265
+
266
+ test 'defaults to nil app_name' do
267
+ assert_equal(nil, new_cli.send(:options)[:app_name])
268
+ end
269
+
270
+ test 'accepts app_name via -n' do
271
+ cli = new_cli(%w(-n hambone))
272
+ cli.parse_options
273
+ assert_equal('hambone', cli.send(:options)[:app_name])
274
+ end
275
+
276
+ test 'accepts app_name via --app-name' do
277
+ cli = new_cli(%w(--app-name flimsy))
278
+ cli.parse_options
279
+ assert_equal('flimsy', cli.send(:options)[:app_name])
280
+ end
281
+
282
+ test 'runs Resque::Scheduler' do
283
+ Resque::Scheduler.expects(:run)
284
+ ResqueScheduler::Cli.run!([], {})
285
+ end
286
+ end
@@ -1,4 +1,4 @@
1
- require File.dirname(__FILE__) + '/test_helper'
1
+ require_relative 'test_helper'
2
2
 
3
3
  context "DelayedQueue" do
4
4
 
@@ -313,6 +313,75 @@ context "DelayedQueue" do
313
313
  assert_equal(2, Resque.count_all_scheduled_jobs)
314
314
  end
315
315
 
316
+ test "remove_delayed_selection removes multiple items matching arguments at same timestamp" do
317
+ t = Time.now + 120
318
+ Resque.enqueue_at(t, SomeIvarJob, "bar", "llama")
319
+ Resque.enqueue_at(t, SomeIvarJob, "foo")
320
+ Resque.enqueue_at(t, SomeIvarJob, "bar", "monkey")
321
+ Resque.enqueue_at(t, SomeIvarJob, "bar", "platypus")
322
+ Resque.enqueue_at(t, SomeIvarJob, "baz")
323
+ Resque.enqueue_at(t, SomeIvarJob, "bar", "llama")
324
+ Resque.enqueue_at(t, SomeIvarJob, "bar", "llama")
325
+
326
+ assert_equal(5, Resque.remove_delayed_selection {|args| args[0] == 'bar'})
327
+ assert_equal(2, Resque.count_all_scheduled_jobs)
328
+ end
329
+
330
+ test "remove_delayed_selection removes single item matching arguments" do
331
+ t = Time.now + 120
332
+ Resque.enqueue_at(t, SomeIvarJob, "foo")
333
+ Resque.enqueue_at(t + 1, SomeIvarJob, "bar")
334
+ Resque.enqueue_at(t + 2, SomeIvarJob, "bar")
335
+ Resque.enqueue_at(t + 3, SomeIvarJob, "baz")
336
+
337
+ assert_equal(1, Resque.remove_delayed_selection {|args| args[0] == 'foo'})
338
+ assert_equal(3, Resque.count_all_scheduled_jobs)
339
+ end
340
+
341
+ test "remove_delayed_selection removes multiple items matching arguments" do
342
+ t = Time.now + 120
343
+ Resque.enqueue_at(t, SomeIvarJob, "foo")
344
+ Resque.enqueue_at(t + 1, SomeIvarJob, "bar")
345
+ Resque.enqueue_at(t + 2, SomeIvarJob, "bar")
346
+ Resque.enqueue_at(t + 3, SomeIvarJob, "baz")
347
+
348
+ assert_equal(2, Resque.remove_delayed_selection {|args| args[0] == 'bar'})
349
+ assert_equal(2, Resque.count_all_scheduled_jobs)
350
+ end
351
+
352
+ test "remove_delayed_selection removes multiple items matching arguments as hash" do
353
+ t = Time.now + 120
354
+ Resque.enqueue_at(t, SomeIvarJob, :foo => "foo")
355
+ Resque.enqueue_at(t + 1, SomeIvarJob, :foo => "bar")
356
+ Resque.enqueue_at(t + 2, SomeIvarJob, :foo => "bar")
357
+ Resque.enqueue_at(t + 3, SomeIvarJob, :foo => "baz")
358
+
359
+ assert_equal(2, Resque.remove_delayed_selection {|args| args[0]['foo'] == 'bar'})
360
+ assert_equal(2, Resque.count_all_scheduled_jobs)
361
+ end
362
+
363
+ test "remove_delayed_selection ignores jobs with no arguments" do
364
+ t = Time.now + 120
365
+ Resque.enqueue_at(t, SomeIvarJob)
366
+ Resque.enqueue_at(t + 1, SomeIvarJob)
367
+ Resque.enqueue_at(t + 2, SomeIvarJob)
368
+ Resque.enqueue_at(t + 3, SomeIvarJob)
369
+
370
+ assert_equal(0, Resque.remove_delayed_selection {|args| args[0] == 'bar'})
371
+ assert_equal(4, Resque.count_all_scheduled_jobs)
372
+ end
373
+
374
+ test "remove_delayed_selection doesn't remove items it shouldn't" do
375
+ t = Time.now + 120
376
+ Resque.enqueue_at(t, SomeIvarJob, "foo")
377
+ Resque.enqueue_at(t + 1, SomeIvarJob, "bar")
378
+ Resque.enqueue_at(t + 2, SomeIvarJob, "bar")
379
+ Resque.enqueue_at(t + 3, SomeIvarJob, "baz")
380
+
381
+ assert_equal(0, Resque.remove_delayed_selection {|args| args[0] == 'qux'})
382
+ assert_equal(4, Resque.count_all_scheduled_jobs)
383
+ end
384
+
316
385
  test "remove_delayed_job_from_timestamp removes instances of jobs at a given timestamp" do
317
386
  t = Time.now + 120
318
387
  Resque.enqueue_at(t, SomeIvarJob, "foo")