resque-scheduler 2.5.1 → 4.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/funding.yml +4 -0
  4. data/.github/workflows/codeql-analysis.yml +59 -0
  5. data/.github/workflows/rubocop.yml +27 -0
  6. data/.github/workflows/ruby.yml +81 -0
  7. data/AUTHORS.md +25 -0
  8. data/CHANGELOG.md +539 -0
  9. data/CODE_OF_CONDUCT.md +74 -0
  10. data/Gemfile +26 -2
  11. data/README.md +291 -70
  12. data/Rakefile +8 -19
  13. data/exe/resque-scheduler +5 -0
  14. data/lib/resque/scheduler/cli.rb +147 -0
  15. data/lib/resque/scheduler/configuration.rb +102 -0
  16. data/lib/resque/scheduler/delaying_extensions.rb +371 -0
  17. data/lib/resque/scheduler/env.rb +85 -0
  18. data/lib/resque/scheduler/extension.rb +13 -0
  19. data/lib/resque/scheduler/failure_handler.rb +11 -0
  20. data/lib/resque/scheduler/lock/base.rb +13 -4
  21. data/lib/resque/scheduler/lock/basic.rb +4 -5
  22. data/lib/resque/scheduler/lock/resilient.rb +52 -43
  23. data/lib/resque/scheduler/lock.rb +2 -1
  24. data/lib/resque/scheduler/locking.rb +104 -0
  25. data/lib/resque/scheduler/logger_builder.rb +83 -0
  26. data/lib/resque/scheduler/plugin.rb +31 -0
  27. data/lib/resque/scheduler/scheduling_extensions.rb +142 -0
  28. data/lib/{resque_scheduler → resque/scheduler}/server/views/delayed.erb +21 -12
  29. data/lib/{resque_scheduler → resque/scheduler}/server/views/delayed_schedules.erb +1 -1
  30. data/lib/{resque_scheduler → resque/scheduler}/server/views/delayed_timestamp.erb +1 -1
  31. data/lib/resque/scheduler/server/views/scheduler.erb +58 -0
  32. data/lib/{resque_scheduler → resque/scheduler}/server/views/search.erb +4 -7
  33. data/lib/{resque_scheduler → resque/scheduler}/server/views/search_form.erb +1 -5
  34. data/lib/resque/scheduler/server.rb +268 -0
  35. data/lib/resque/scheduler/signal_handling.rb +40 -0
  36. data/lib/{resque_scheduler → resque/scheduler}/tasks.rb +3 -6
  37. data/lib/resque/scheduler/util.rb +39 -0
  38. data/lib/resque/scheduler/version.rb +7 -0
  39. data/lib/resque/scheduler.rb +271 -199
  40. data/lib/resque-scheduler.rb +3 -1
  41. data/resque-scheduler.gemspec +53 -20
  42. metadata +176 -132
  43. data/.gitignore +0 -11
  44. data/.rubocop.yml +0 -129
  45. data/.simplecov +0 -1
  46. data/.travis.yml +0 -21
  47. data/HISTORY.md +0 -226
  48. data/ROADMAP.md +0 -10
  49. data/bin/resque-scheduler +0 -5
  50. data/examples/Rakefile +0 -2
  51. data/examples/config/initializers/resque-web.rb +0 -37
  52. data/examples/dynamic-scheduling/README.md +0 -28
  53. data/examples/dynamic-scheduling/app/jobs/fix_schedules_job.rb +0 -54
  54. data/examples/dynamic-scheduling/app/jobs/send_email_job.rb +0 -9
  55. data/examples/dynamic-scheduling/app/models/user.rb +0 -16
  56. data/examples/dynamic-scheduling/config/resque.yml +0 -4
  57. data/examples/dynamic-scheduling/config/static_schedule.yml +0 -7
  58. data/examples/dynamic-scheduling/lib/tasks/resque.rake +0 -48
  59. data/examples/run-resque-web +0 -3
  60. data/lib/resque/scheduler_locking.rb +0 -91
  61. data/lib/resque_scheduler/cli.rb +0 -160
  62. data/lib/resque_scheduler/logger_builder.rb +0 -70
  63. data/lib/resque_scheduler/plugin.rb +0 -28
  64. data/lib/resque_scheduler/server/views/scheduler.erb +0 -36
  65. data/lib/resque_scheduler/server.rb +0 -182
  66. data/lib/resque_scheduler/util.rb +0 -34
  67. data/lib/resque_scheduler/version.rb +0 -5
  68. data/lib/resque_scheduler.rb +0 -386
  69. data/script/migrate_to_timestamps_set.rb +0 -14
  70. data/tasks/resque_scheduler.rake +0 -2
  71. data/test/cli_test.rb +0 -286
  72. data/test/delayed_queue_test.rb +0 -449
  73. data/test/redis-test.conf +0 -108
  74. data/test/resque-web_test.rb +0 -199
  75. data/test/scheduler_args_test.rb +0 -190
  76. data/test/scheduler_hooks_test.rb +0 -23
  77. data/test/scheduler_locking_test.rb +0 -242
  78. data/test/scheduler_setup_test.rb +0 -95
  79. data/test/scheduler_task_test.rb +0 -35
  80. data/test/scheduler_test.rb +0 -344
  81. data/test/support/redis_instance.rb +0 -134
  82. data/test/test_helper.rb +0 -131
  83. /data/lib/{resque_scheduler → resque/scheduler}/server/views/requeue-params.erb +0 -0
@@ -1,95 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- context "Resque::Scheduler" do
4
- setup do
5
- ENV['VERBOSE'] = nil
6
- nullify_logger
7
- Resque::Scheduler.dynamic = false
8
- Resque.redis.flushall
9
- Resque::Scheduler.clear_schedule!
10
- end
11
-
12
- teardown { restore_devnull_logfile }
13
-
14
- test 'set custom logger' do
15
- custom_logger = Logger.new('/dev/null')
16
- Resque::Scheduler.logger = custom_logger
17
- assert_equal(custom_logger, Resque::Scheduler.logger)
18
- end
19
-
20
- test 'configure block' do
21
- Resque::Scheduler.mute = false
22
- Resque::Scheduler.configure do |c|
23
- c.mute = true
24
- end
25
- assert_equal(Resque::Scheduler.mute, true)
26
- end
27
-
28
- context 'when getting the env' do
29
- def wipe
30
- Resque::Scheduler.env = nil
31
- Rails.env = nil
32
- ENV['RAILS_ENV'] = nil
33
- end
34
-
35
- setup { wipe }
36
- teardown { wipe }
37
-
38
- test 'uses the value if set' do
39
- Resque::Scheduler.env = 'foo'
40
- assert_equal('foo', Resque::Scheduler.env)
41
- end
42
-
43
- test 'uses Rails.env if present' do
44
- Rails.env = 'bar'
45
- assert_equal('bar', Resque::Scheduler.env)
46
- end
47
-
48
- test 'uses $RAILS_ENV if present' do
49
- ENV['RAILS_ENV'] = 'baz'
50
- assert_equal('baz', Resque::Scheduler.env)
51
- end
52
- end
53
-
54
- context 'logger default settings' do
55
- setup { nullify_logger }
56
- teardown { restore_devnull_logfile }
57
-
58
- test 'uses STDOUT' do
59
- assert_equal(
60
- Resque::Scheduler.logger.instance_variable_get(:@logdev).dev, $stdout
61
- )
62
- end
63
-
64
- test 'not verbose' do
65
- assert Resque::Scheduler.logger.level > Logger::DEBUG
66
- end
67
-
68
- test 'not muted' do
69
- assert Resque::Scheduler.logger.level < Logger::FATAL
70
- end
71
- end
72
-
73
- context 'logger custom settings' do
74
- setup { nullify_logger }
75
- teardown { restore_devnull_logfile }
76
-
77
- test 'uses logfile' do
78
- Resque::Scheduler.logfile = '/dev/null'
79
- assert_equal(
80
- Resque::Scheduler.logger.instance_variable_get(:@logdev).filename,
81
- '/dev/null'
82
- )
83
- end
84
-
85
- test 'set verbosity' do
86
- Resque::Scheduler.verbose = true
87
- assert Resque::Scheduler.logger.level == Logger::DEBUG
88
- end
89
-
90
- test 'mute logger' do
91
- Resque::Scheduler.mute = true
92
- assert Resque::Scheduler.logger.level == Logger::FATAL
93
- end
94
- end
95
- end
@@ -1,35 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- context "Resque::Scheduler" do
4
- setup do
5
- Resque::Scheduler.dynamic = false
6
- Resque.redis.flushall
7
- Resque::Scheduler.mute = true
8
- Resque::Scheduler.clear_schedule!
9
- Resque::Scheduler.send(:class_variable_set, :@@scheduled_jobs, {})
10
- Resque::Scheduler.send(:instance_variable_set, :@shutdown, false)
11
- end
12
-
13
- test "shutdown raises Interrupt when sleeping" do
14
- Thread.current.expects(:raise).with(Interrupt)
15
- Resque::Scheduler.send(:instance_variable_set, :@th, Thread.current)
16
- Resque::Scheduler.send(:instance_variable_set, :@sleeping, true)
17
- Resque::Scheduler.shutdown
18
- end
19
-
20
- test "sending TERM to scheduler breaks out of poll_sleep" do
21
- Resque::Scheduler.expects(:release_master_lock!)
22
- fork do
23
- sleep(0.5)
24
- system("kill -TERM #{Process.ppid}")
25
- exit!
26
- end
27
-
28
- assert_raises SystemExit do
29
- Resque::Scheduler.run
30
- end
31
-
32
- Resque::Scheduler.unstub(:release_master_lock!)
33
- Resque::Scheduler.release_master_lock!
34
- end
35
- end
@@ -1,344 +0,0 @@
1
- require_relative 'test_helper'
2
-
3
- context 'Resque::Scheduler' do
4
- setup do
5
- Resque::Scheduler.configure do |c|
6
- c.dynamic = false
7
- c.mute = true
8
- c.env = nil
9
- c.app_name = nil
10
- end
11
- Resque.redis.flushall
12
- Resque::Scheduler.clear_schedule!
13
- Resque::Scheduler.send(:class_variable_set, :@@scheduled_jobs, {})
14
- end
15
-
16
- test 'enqueue constantizes' do
17
- Resque::Scheduler.env = 'production'
18
- config = {
19
- 'cron' => '* * * * *',
20
- 'class' => 'SomeRealClass',
21
- 'args' => '/tmp'
22
- }
23
- Resque::Job.expects(:create).with(
24
- SomeRealClass.queue, SomeRealClass, '/tmp'
25
- )
26
- Resque::Scheduler.enqueue_from_config(config)
27
- end
28
-
29
- test 'enqueue runs hooks' do
30
- Resque::Scheduler.env = 'production'
31
- config = {
32
- 'cron' => '* * * * *',
33
- 'class' => 'SomeRealClass',
34
- 'args' => '/tmp'
35
- }
36
-
37
- Resque::Job.expects(:create).with(
38
- SomeRealClass.queue, SomeRealClass, '/tmp'
39
- )
40
- SomeRealClass.expects(:before_delayed_enqueue_example).with('/tmp')
41
- SomeRealClass.expects(:before_enqueue_example).with('/tmp')
42
- SomeRealClass.expects(:after_enqueue_example).with('/tmp')
43
-
44
- Resque::Scheduler.enqueue_from_config(config)
45
- end
46
-
47
- test 'enqueue_from_config respects queue params' do
48
- config = {
49
- 'cron' => '* * * * *',
50
- 'class' => 'SomeIvarJob',
51
- 'queue' => 'high'
52
- }
53
- Resque.expects(:enqueue_to).with('high', SomeIvarJob)
54
- Resque::Scheduler.enqueue_from_config(config)
55
- end
56
-
57
- test "config makes it into the rufus_scheduler" do
58
- assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
59
-
60
- Resque.schedule = {:some_ivar_job => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
61
- Resque::Scheduler.load_schedule!
62
-
63
- assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
64
- assert Resque::Scheduler.scheduled_jobs.include?('some_ivar_job')
65
- end
66
-
67
- test "can reload schedule" do
68
- Resque::Scheduler.dynamic = true
69
- Resque.schedule = {"some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"}}
70
-
71
- Resque::Scheduler.load_schedule!
72
-
73
- assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
74
- assert Resque::Scheduler.scheduled_jobs.include?("some_ivar_job")
75
-
76
- Resque.redis.del(:schedules)
77
- Resque.redis.hset(:schedules, "some_ivar_job2", Resque.encode(
78
- 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"
79
- ))
80
-
81
- Resque::Scheduler.reload_schedule!
82
-
83
- assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
84
-
85
- assert_equal '/tmp/2', Resque.schedule["some_ivar_job2"]["args"]
86
- assert Resque::Scheduler.scheduled_jobs.include?("some_ivar_job2")
87
- end
88
-
89
- test 'load_schedule_job loads a schedule' do
90
- Resque::Scheduler.load_schedule_job(
91
- 'some_ivar_job', {
92
- 'cron' => '* * * * *',
93
- 'class' => 'SomeIvarJob',
94
- 'args' => '/tmp'
95
- }
96
- )
97
-
98
- assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
99
- assert_equal(1, Resque::Scheduler.scheduled_jobs.size)
100
- assert Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
101
- end
102
-
103
- test 'load_schedule_job with every with options' do
104
- Resque::Scheduler.load_schedule_job(
105
- 'some_ivar_job', {
106
- 'every' => ['30s', { 'first_in' => '60s' }],
107
- 'class' => 'SomeIvarJob',
108
- 'args' => '/tmp'
109
- }
110
- )
111
-
112
- assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
113
- assert_equal(1, Resque::Scheduler.scheduled_jobs.size)
114
- assert Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
115
- job = Resque::Scheduler.scheduled_jobs['some_ivar_job']
116
- assert job.params.keys.include?(:first_in)
117
- end
118
-
119
- test 'load_schedule_job with cron with options' do
120
- Resque::Scheduler.load_schedule_job(
121
- 'some_ivar_job', {
122
- 'cron' => ['* * * * *', { 'allow_overlapping' => 'true' }],
123
- 'class' => 'SomeIvarJob',
124
- 'args' => '/tmp'
125
- }
126
- )
127
-
128
- assert_equal(1, Resque::Scheduler.rufus_scheduler.all_jobs.size)
129
- assert_equal(1, Resque::Scheduler.scheduled_jobs.size)
130
- assert Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
131
- job = Resque::Scheduler.scheduled_jobs['some_ivar_job']
132
- assert job.params.keys.include?(:allow_overlapping)
133
- end
134
-
135
- test 'load_schedule_job without cron' do
136
- Resque::Scheduler.load_schedule_job(
137
- 'some_ivar_job', {
138
- 'class' => 'SomeIvarJob',
139
- 'args' => '/tmp'
140
- }
141
- )
142
-
143
- assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
144
- assert_equal(0, Resque::Scheduler.scheduled_jobs.size)
145
- assert !Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
146
- end
147
-
148
- test 'load_schedule_job with an empty cron' do
149
- Resque::Scheduler.load_schedule_job(
150
- 'some_ivar_job', {
151
- 'cron' => '',
152
- 'class' => 'SomeIvarJob',
153
- 'args' => '/tmp'
154
- }
155
- )
156
-
157
- assert_equal(0, Resque::Scheduler.rufus_scheduler.all_jobs.size)
158
- assert_equal(0, Resque::Scheduler.scheduled_jobs.size)
159
- assert !Resque::Scheduler.scheduled_jobs.keys.include?('some_ivar_job')
160
- end
161
-
162
- test "update_schedule" do
163
- Resque::Scheduler.dynamic = true
164
- Resque.schedule = {
165
- "some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"},
166
- "another_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/5"},
167
- "stay_put_job" => {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
168
- }
169
-
170
- Resque::Scheduler.load_schedule!
171
-
172
- Resque.set_schedule("some_ivar_job",
173
- {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"}
174
- )
175
- Resque.set_schedule("new_ivar_job",
176
- {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp/3"}
177
- )
178
- Resque.set_schedule("stay_put_job",
179
- {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
180
- )
181
- Resque.remove_schedule("another_ivar_job")
182
-
183
- Resque::Scheduler.update_schedule
184
-
185
- assert_equal(3, Resque::Scheduler.rufus_scheduler.all_jobs.size)
186
- assert_equal(3, Resque::Scheduler.scheduled_jobs.size)
187
- %w(some_ivar_job new_ivar_job stay_put_job).each do |job_name|
188
- assert Resque::Scheduler.scheduled_jobs.keys.include?(job_name)
189
- assert Resque.schedule.keys.include?(job_name)
190
- end
191
- assert !Resque::Scheduler.scheduled_jobs.keys.include?("another_ivar_job")
192
- assert !Resque.schedule.keys.include?("another_ivar_job")
193
- assert_equal 0, Resque.redis.scard(:schedules_changed)
194
- end
195
-
196
- test "update_schedule with mocks" do
197
- Resque::Scheduler.dynamic = true
198
- Resque.schedule = {
199
- "some_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp"},
200
- "another_ivar_job" => {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/5"},
201
- "stay_put_job" => {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
202
- }
203
-
204
- Resque::Scheduler.load_schedule!
205
-
206
- Resque::Scheduler.rufus_scheduler.expects(:unschedule).with(Resque::Scheduler.scheduled_jobs["some_ivar_job"].job_id)
207
- Resque::Scheduler.rufus_scheduler.expects(:unschedule).with(Resque::Scheduler.scheduled_jobs["another_ivar_job"].job_id)
208
-
209
- Resque.set_schedule("some_ivar_job",
210
- {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"}
211
- )
212
- Resque.set_schedule("new_ivar_job",
213
- {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp/3"}
214
- )
215
- Resque.set_schedule("stay_put_job",
216
- {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp"}
217
- )
218
- Resque.remove_schedule("another_ivar_job")
219
-
220
- Resque::Scheduler.update_schedule
221
-
222
- assert_equal(3, Resque::Scheduler.scheduled_jobs.size)
223
- %w(some_ivar_job new_ivar_job stay_put_job).each do |job_name|
224
- assert Resque::Scheduler.scheduled_jobs.keys.include?(job_name)
225
- assert Resque.schedule.keys.include?(job_name)
226
- end
227
- assert !Resque::Scheduler.scheduled_jobs.keys.include?("another_ivar_job")
228
- assert !Resque.schedule.keys.include?("another_ivar_job")
229
- assert_equal 0, Resque.redis.scard(:schedules_changed)
230
- end
231
-
232
- test "schedule= sets the schedule" do
233
- Resque::Scheduler.dynamic = true
234
- Resque.schedule = {"my_ivar_job" => {
235
- 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/75"
236
- }}
237
- assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/75"},
238
- Resque.decode(Resque.redis.hget(:schedules, "my_ivar_job")))
239
- end
240
-
241
- test "schedule= removes schedules not present in the given schedule argument" do
242
- Resque::Scheduler.dynamic = true
243
-
244
- Resque.schedule = {"old_job" => {'cron' => "* * * * *", 'class' => 'OldJob'}}
245
- assert_equal({"old_job" => {'cron' => "* * * * *", 'class' => 'OldJob'}}, Resque.schedule)
246
-
247
- Resque.schedule = {"new_job" => {'cron' => "* * * * *", 'class' => 'NewJob'}}
248
- Resque.reload_schedule!
249
- assert_equal({"new_job" => {'cron' => "* * * * *", 'class' => 'NewJob'}}, Resque.schedule)
250
- end
251
-
252
- test "schedule= uses job name as 'class' argument if it's missing" do
253
- Resque::Scheduler.dynamic = true
254
- Resque.schedule = {"SomeIvarJob" => {
255
- 'cron' => "* * * * *", 'args' => "/tmp/75"
256
- }}
257
- assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/75"},
258
- Resque.decode(Resque.redis.hget(:schedules, "SomeIvarJob")))
259
- assert_equal('SomeIvarJob', Resque.schedule['SomeIvarJob']['class'])
260
- end
261
-
262
- test "schedule= does not mutate argument" do
263
- schedule = {"SomeIvarJob" => {
264
- 'cron' => "* * * * *", 'args' => "/tmp/75"
265
- }}
266
- Resque.schedule = schedule
267
- assert !schedule['SomeIvarJob'].key?('class')
268
- end
269
-
270
- test "set_schedule can set an individual schedule" do
271
- Resque.set_schedule("some_ivar_job", {
272
- 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/22"
273
- })
274
- assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/22"},
275
- Resque.decode(Resque.redis.hget(:schedules, "some_ivar_job")))
276
- assert Resque.redis.sismember(:schedules_changed, "some_ivar_job")
277
- end
278
-
279
- test "get_schedule returns a schedule" do
280
- Resque.redis.hset(:schedules, "some_ivar_job2", Resque.encode(
281
- 'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/33"
282
- ))
283
- assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/33"},
284
- Resque.get_schedule("some_ivar_job2"))
285
- end
286
-
287
- test "remove_schedule removes a schedule" do
288
- Resque.set_schedule("some_ivar_job3",
289
- {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/44", 'persist' => true}
290
- )
291
- Resque::Scheduler.load_schedule!
292
- Resque.remove_schedule("some_ivar_job3")
293
- assert_equal nil, Resque.redis.hget(:schedules, "some_ivar_job3")
294
- assert Resque.redis.sismember(:schedules_changed, "some_ivar_job3")
295
- assert_equal [], Resque.redis.smembers(:persisted_schedules)
296
- end
297
-
298
- test "persisted schedules" do
299
- Resque.set_schedule("some_ivar_job",
300
- {'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2", 'persist' => true}
301
- )
302
- Resque.set_schedule("new_ivar_job",
303
- {'cron' => "* * * * *", 'class' => 'SomeJob', 'args' => "/tmp/3"}
304
- )
305
-
306
- Resque.schedule=({
307
- 'a_schedule' => {'cron' => "* * * * *", 'class' => 'SomeOtherJob', 'args' => '/tmp'}
308
- })
309
- Resque::Scheduler.load_schedule!
310
-
311
- assert_equal({'cron' => "* * * * *", 'class' => 'SomeIvarJob', 'args' => "/tmp/2"},
312
- Resque.schedule['some_ivar_job'])
313
- assert_equal(nil, Resque.schedule['some_job'])
314
- end
315
-
316
- test "adheres to lint" do
317
- assert_nothing_raised do
318
- Resque::Plugin.lint(Resque::Scheduler)
319
- Resque::Plugin.lint(ResqueScheduler)
320
- end
321
- end
322
-
323
- test 'procline contains app_name when present' do
324
- Resque::Scheduler.app_name = 'foo'
325
- assert Resque::Scheduler.send(:build_procline, 'bar') =~ /\[foo\]:/
326
- end
327
-
328
- test 'procline omits app_name when absent' do
329
- Resque::Scheduler.app_name = nil
330
- assert Resque::Scheduler.send(:build_procline, 'bar') =~
331
- /#{Resque::Scheduler.send(:internal_name)}: bar/
332
- end
333
-
334
- test 'procline contains env when present' do
335
- Resque::Scheduler.env = 'derp'
336
- assert Resque::Scheduler.send(:build_procline, 'cage') =~ /\[derp\]: cage/
337
- end
338
-
339
- test 'procline omits env when absent' do
340
- Resque::Scheduler.env = nil
341
- assert Resque::Scheduler.send(:build_procline, 'cage') =~
342
- /#{Resque::Scheduler.send(:internal_name)}: cage/
343
- end
344
- end
@@ -1,134 +0,0 @@
1
- require 'socket'
2
- require 'timeout'
3
- require 'fileutils'
4
-
5
- class RedisInstance
6
- class << self
7
- @running = false
8
- @port = nil
9
- @pid = nil
10
-
11
- def run_if_needed!
12
- run! unless running?
13
- end
14
-
15
- def run!
16
- ensure_redis_server_present!
17
- ensure_pid_directory
18
- reassign_redis_clients
19
- start_redis_server
20
-
21
- if $?.success?
22
- wait_for_pid
23
- puts "Booted isolated Redis on port #{port} with PID #{pid}."
24
-
25
- wait_for_redis_boot
26
-
27
- # Ensure we tear down Redis on Ctrl+C / test failure.
28
- at_exit { stop! }
29
- else
30
- fail "Failed to start Redis on port #{port}."
31
- end
32
-
33
- @running = true
34
- end
35
-
36
- def stop!
37
- $stdout.puts "Sending TERM to Redis (#{pid})..."
38
- Process.kill('TERM', pid)
39
-
40
- @port = nil
41
- @running = false
42
- @pid = nil
43
- end
44
-
45
- def running?
46
- @running
47
- end
48
-
49
- private
50
-
51
- def ensure_redis_server_present!
52
- if !system('redis-server -v')
53
- fail "** can't find `redis-server` in your path"
54
- end
55
- end
56
-
57
- def wait_for_redis_boot
58
- Timeout::timeout(10) do
59
- begin
60
- while Resque.redis.ping != 'PONG'
61
- end
62
- rescue
63
- # silence all errors
64
- end
65
- end
66
- end
67
-
68
- def ensure_pid_directory
69
- FileUtils.mkdir_p(File.dirname(pid_file))
70
- end
71
-
72
- def reassign_redis_clients
73
- Resque.redis = Redis.new(:hostname => '127.0.0.1', :port => port, :thread_safe => true)
74
- end
75
-
76
- def start_redis_server
77
- IO.popen("redis-server -", "w+") do |server|
78
- server.write(config)
79
- server.close_write
80
- end
81
- end
82
-
83
- def pid
84
- @pid ||= File.read(pid_file).to_i
85
- end
86
-
87
- def wait_for_pid
88
- Timeout::timeout(10) do
89
- while !File.exist?(pid_file)
90
- end
91
- end
92
- end
93
-
94
- def port
95
- @port ||= random_port
96
- end
97
-
98
- def pid_file
99
- "/tmp/redis-scheduler-test.pid"
100
- end
101
-
102
- def config
103
- <<-EOF
104
- daemonize yes
105
- pidfile #{pid_file}
106
- port #{port}
107
- EOF
108
- end
109
-
110
- # Returns a random port in the upper (10000-65535) range.
111
- def random_port
112
- ports = (10000..65535).to_a
113
-
114
- loop do
115
- port = ports[rand(ports.size)]
116
- return port if port_available?('127.0.0.1', port)
117
- end
118
- end
119
-
120
- def port_available?(ip, port, seconds=1)
121
- Timeout::timeout(seconds) do
122
- begin
123
- TCPSocket.new(ip, port).close
124
- false
125
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
126
- true
127
- end
128
- end
129
- rescue Timeout::Error
130
- true
131
- end
132
- end
133
- end
134
-