rufus-scheduler 3.0.8 → 3.2.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.
- data/CHANGELOG.txt +75 -0
- data/CREDITS.txt +21 -0
- data/LICENSE.txt +1 -1
- data/README.md +120 -15
- data/lib/rufus/scheduler/cronline.rb +107 -100
- data/lib/rufus/scheduler/job_array.rb +2 -1
- data/lib/rufus/scheduler/jobs.rb +53 -41
- data/lib/rufus/scheduler/locks.rb +95 -0
- data/lib/rufus/scheduler/util.rb +8 -33
- data/lib/rufus/scheduler/zones.rb +175 -0
- data/lib/rufus/scheduler/zotime.rb +167 -0
- data/lib/rufus/scheduler.rb +67 -67
- data/rufus-scheduler.gemspec +3 -28
- metadata +22 -47
- data/spec/basics_spec.rb +0 -49
- data/spec/cronline_spec.rb +0 -681
- data/spec/custom_locks_spec.rb +0 -47
- data/spec/error_spec.rb +0 -139
- data/spec/job_array_spec.rb +0 -39
- data/spec/job_at_spec.rb +0 -58
- data/spec/job_cron_spec.rb +0 -106
- data/spec/job_every_spec.rb +0 -90
- data/spec/job_in_spec.rb +0 -20
- data/spec/job_interval_spec.rb +0 -68
- data/spec/job_repeat_spec.rb +0 -356
- data/spec/job_spec.rb +0 -631
- data/spec/lockfile_spec.rb +0 -61
- data/spec/parse_spec.rb +0 -261
- data/spec/schedule_at_spec.rb +0 -158
- data/spec/schedule_cron_spec.rb +0 -66
- data/spec/schedule_every_spec.rb +0 -109
- data/spec/schedule_in_spec.rb +0 -80
- data/spec/schedule_interval_spec.rb +0 -128
- data/spec/scheduler_spec.rb +0 -1049
- data/spec/spec_helper.rb +0 -126
- data/spec/threads_spec.rb +0 -96
data/spec/job_spec.rb
DELETED
|
@@ -1,631 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# Specifying rufus-scheduler
|
|
4
|
-
#
|
|
5
|
-
# Wed Apr 17 06:00:59 JST 2013
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
require 'spec_helper'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
describe Rufus::Scheduler::Job do
|
|
12
|
-
|
|
13
|
-
# specify behaviours common to all job classes
|
|
14
|
-
|
|
15
|
-
before :each do
|
|
16
|
-
|
|
17
|
-
@taoe = Thread.abort_on_exception
|
|
18
|
-
Thread.abort_on_exception = false
|
|
19
|
-
|
|
20
|
-
@ose = $stderr
|
|
21
|
-
$stderr = StringIO.new
|
|
22
|
-
|
|
23
|
-
@scheduler = Rufus::Scheduler.new
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
after :each do
|
|
27
|
-
|
|
28
|
-
@scheduler.shutdown
|
|
29
|
-
|
|
30
|
-
Thread.abort_on_exception = @taoe
|
|
31
|
-
|
|
32
|
-
$stderr = @ose
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
describe '#last_time' do
|
|
36
|
-
|
|
37
|
-
it 'returns nil if the job never fired' do
|
|
38
|
-
|
|
39
|
-
job = @scheduler.schedule_in '10d' do; end
|
|
40
|
-
|
|
41
|
-
expect(job.last_time).to eq(nil)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it 'returns the last time the job fired' do
|
|
45
|
-
|
|
46
|
-
job = @scheduler.schedule_in '0s' do; end
|
|
47
|
-
|
|
48
|
-
sleep 0.4
|
|
49
|
-
|
|
50
|
-
expect(job.last_time).not_to eq(nil)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
describe '#threads' do
|
|
55
|
-
|
|
56
|
-
it 'returns an empty list when the job is not running' do
|
|
57
|
-
|
|
58
|
-
job = @scheduler.in('1d', :job => true) {}
|
|
59
|
-
|
|
60
|
-
expect(job.threads.size).to eq(0)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
it 'returns an empty list after the job terminated' do
|
|
64
|
-
|
|
65
|
-
job = @scheduler.in('0s', :job => true) {}
|
|
66
|
-
|
|
67
|
-
sleep 0.8
|
|
68
|
-
|
|
69
|
-
expect(job.threads.size).to eq(0)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it 'lists the threads the job currently runs in' do
|
|
73
|
-
|
|
74
|
-
job =
|
|
75
|
-
@scheduler.schedule_in('0s') do
|
|
76
|
-
sleep(1)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
sleep 0.4
|
|
80
|
-
|
|
81
|
-
expect(job.threads.size).to eq(1)
|
|
82
|
-
|
|
83
|
-
t = job.threads.first
|
|
84
|
-
expect(t[:rufus_scheduler_job]).to eq(job)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
describe '#kill' do
|
|
89
|
-
|
|
90
|
-
it 'has no effect if the job is not running' do
|
|
91
|
-
|
|
92
|
-
job = @scheduler.schedule_in '10d' do; end
|
|
93
|
-
|
|
94
|
-
tls = Thread.list.size
|
|
95
|
-
|
|
96
|
-
job.kill
|
|
97
|
-
|
|
98
|
-
expect(Thread.list.size).to eq(tls)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it 'makes the threads vacant' do
|
|
102
|
-
|
|
103
|
-
counter = 0
|
|
104
|
-
|
|
105
|
-
job =
|
|
106
|
-
@scheduler.schedule_in '0s' do
|
|
107
|
-
sleep 2
|
|
108
|
-
counter = counter + 1
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
sleep 1
|
|
112
|
-
|
|
113
|
-
v0 = @scheduler.work_threads(:vacant).size
|
|
114
|
-
a0 = @scheduler.work_threads(:active).size
|
|
115
|
-
|
|
116
|
-
job.kill
|
|
117
|
-
|
|
118
|
-
sleep 2
|
|
119
|
-
|
|
120
|
-
v1 = @scheduler.work_threads(:vacant).size
|
|
121
|
-
a1 = @scheduler.work_threads(:active).size
|
|
122
|
-
|
|
123
|
-
expect(counter).to eq(0)
|
|
124
|
-
|
|
125
|
-
expect(v0).to eq(0)
|
|
126
|
-
expect(a0).to eq(1)
|
|
127
|
-
|
|
128
|
-
expect(v1).to eq(1)
|
|
129
|
-
expect(a1).to eq(0)
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
describe '#running?' do
|
|
134
|
-
|
|
135
|
-
it 'returns false when the job is not running in any thread' do
|
|
136
|
-
|
|
137
|
-
job = @scheduler.in('1d', :job => true) {}
|
|
138
|
-
|
|
139
|
-
expect(job.running?).to eq(false)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
it 'returns true when the job is running in at least one thread' do
|
|
143
|
-
|
|
144
|
-
job = @scheduler.in('0s', :job => true) { sleep(1) }
|
|
145
|
-
|
|
146
|
-
sleep 0.4
|
|
147
|
-
|
|
148
|
-
expect(job.running?).to eq(true)
|
|
149
|
-
end
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
describe '#scheduled?' do
|
|
153
|
-
|
|
154
|
-
it 'returns true when the job is scheduled' do
|
|
155
|
-
|
|
156
|
-
job = @scheduler.schedule_in('1d') {}
|
|
157
|
-
|
|
158
|
-
expect(job.scheduled?).to eq(true)
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
it 'returns false when the job is not scheduled' do
|
|
162
|
-
|
|
163
|
-
job = @scheduler.schedule_in('0.1s') {}
|
|
164
|
-
|
|
165
|
-
sleep 0.4
|
|
166
|
-
|
|
167
|
-
expect(job.scheduled?).to eq(false)
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
it 'returns true for repeat jobs that are running' do
|
|
171
|
-
|
|
172
|
-
job = @scheduler.schedule_interval('0.4s') { sleep(10) }
|
|
173
|
-
|
|
174
|
-
sleep 1
|
|
175
|
-
|
|
176
|
-
expect(job.running?).to eq(true)
|
|
177
|
-
expect(job.scheduled?).to eq(true)
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
describe '#call' do
|
|
182
|
-
|
|
183
|
-
it 'calls the job (like it were a proc)' do
|
|
184
|
-
|
|
185
|
-
counter = 0
|
|
186
|
-
|
|
187
|
-
job =
|
|
188
|
-
@scheduler.schedule_in('0.5s') do
|
|
189
|
-
counter = counter + 1
|
|
190
|
-
end
|
|
191
|
-
job.call
|
|
192
|
-
|
|
193
|
-
sleep 0.8
|
|
194
|
-
|
|
195
|
-
expect(counter).to eq(2)
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
describe '#call(true)' do
|
|
200
|
-
|
|
201
|
-
it 'calls the job and let the scheduler handle errors' do
|
|
202
|
-
|
|
203
|
-
$err = nil
|
|
204
|
-
|
|
205
|
-
def @scheduler.on_error(job, err)
|
|
206
|
-
$err = "#{job.class} #{job.original} #{err.message}"
|
|
207
|
-
rescue
|
|
208
|
-
p $!
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
job =
|
|
212
|
-
@scheduler.schedule_in('1d') do
|
|
213
|
-
fail 'again'
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
job.call(true)
|
|
217
|
-
|
|
218
|
-
expect($err).to eq('Rufus::Scheduler::InJob 1d again')
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
describe '#call(false)' do
|
|
223
|
-
|
|
224
|
-
it 'calls the job and let errors slip through' do
|
|
225
|
-
|
|
226
|
-
job =
|
|
227
|
-
@scheduler.schedule_in('1d') do
|
|
228
|
-
fail 'fast'
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
begin
|
|
232
|
-
|
|
233
|
-
#job.call(false)
|
|
234
|
-
job.call # false is the default
|
|
235
|
-
|
|
236
|
-
expect(false).to eq(true)
|
|
237
|
-
|
|
238
|
-
rescue => ex
|
|
239
|
-
|
|
240
|
-
expect(ex.message).to eq('fast')
|
|
241
|
-
end
|
|
242
|
-
end
|
|
243
|
-
end
|
|
244
|
-
|
|
245
|
-
context 'job-local variables' do
|
|
246
|
-
|
|
247
|
-
describe '#[]=' do
|
|
248
|
-
|
|
249
|
-
it 'sets a job-local variable' do
|
|
250
|
-
|
|
251
|
-
job =
|
|
252
|
-
@scheduler.schedule_every '1s' do |job|
|
|
253
|
-
job[:counter] ||= 0
|
|
254
|
-
job[:counter] += 1
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
sleep 3
|
|
258
|
-
|
|
259
|
-
expect(job[:counter]).to be > 1
|
|
260
|
-
end
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
describe '#[]' do
|
|
264
|
-
|
|
265
|
-
it 'returns nil if there is no such entry' do
|
|
266
|
-
|
|
267
|
-
job = @scheduler.schedule_in '1s' do; end
|
|
268
|
-
|
|
269
|
-
expect(job[:nada]).to eq(nil)
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
it 'returns the value of a job-local variable' do
|
|
273
|
-
|
|
274
|
-
job = @scheduler.schedule_in '1s' do; end
|
|
275
|
-
job[:x] = :y
|
|
276
|
-
|
|
277
|
-
expect(job[:x]).to eq(:y)
|
|
278
|
-
end
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
describe '#key?' do
|
|
282
|
-
|
|
283
|
-
it 'returns true if there is an entry with the given key' do
|
|
284
|
-
|
|
285
|
-
job = @scheduler.schedule_in '1s' do; end
|
|
286
|
-
job[:x] = :y
|
|
287
|
-
|
|
288
|
-
expect(job.key?(:x)).to eq(true)
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
describe '#keys' do
|
|
293
|
-
|
|
294
|
-
it 'returns the array of keys of the job-local variables' do
|
|
295
|
-
|
|
296
|
-
job = @scheduler.schedule_in '1s' do; end
|
|
297
|
-
job[:x] = :y
|
|
298
|
-
job['hello'] = :z
|
|
299
|
-
job[123] = {}
|
|
300
|
-
|
|
301
|
-
expect(job.keys.sort_by { |k| k.to_s }).to eq([ 123, 'hello', :x ])
|
|
302
|
-
end
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
context ':tag / :tags => [ t0, t1 ]' do
|
|
307
|
-
|
|
308
|
-
it 'accepts one tag' do
|
|
309
|
-
|
|
310
|
-
job = @scheduler.in '10d', :job => true, :tag => 't0' do; end
|
|
311
|
-
|
|
312
|
-
expect(job.tags).to eq(%w[ t0 ])
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
it 'accepts an array of tags' do
|
|
316
|
-
|
|
317
|
-
job = @scheduler.in '10d', :job => true, :tag => %w[ t0 t1 ] do; end
|
|
318
|
-
|
|
319
|
-
expect(job.tags).to eq(%w[ t0 t1 ])
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
it 'turns tags into strings' do
|
|
323
|
-
|
|
324
|
-
job = @scheduler.in '10d', :job => true, :tags => [ 1, 2 ] do; end
|
|
325
|
-
|
|
326
|
-
expect(job.tags).to eq(%w[ 1 2 ])
|
|
327
|
-
end
|
|
328
|
-
end
|
|
329
|
-
|
|
330
|
-
context ':blocking => true' do
|
|
331
|
-
|
|
332
|
-
it 'runs the job in the same thread as the scheduler thread' do
|
|
333
|
-
|
|
334
|
-
job =
|
|
335
|
-
@scheduler.in('0s', :job => true, :blocking => true) do
|
|
336
|
-
sleep(1)
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
sleep 0.4
|
|
340
|
-
|
|
341
|
-
expect(job.threads.first).to eq(@scheduler.thread)
|
|
342
|
-
|
|
343
|
-
sleep 1.4
|
|
344
|
-
|
|
345
|
-
expect(job.threads.size).to eq(0)
|
|
346
|
-
end
|
|
347
|
-
end
|
|
348
|
-
|
|
349
|
-
context 'default one thread per job behaviour' do
|
|
350
|
-
|
|
351
|
-
it 'runs the job in a dedicated thread' do
|
|
352
|
-
|
|
353
|
-
job =
|
|
354
|
-
@scheduler.in('0s', :job => true) do
|
|
355
|
-
sleep(1)
|
|
356
|
-
end
|
|
357
|
-
|
|
358
|
-
sleep 0.4
|
|
359
|
-
|
|
360
|
-
expect(job.threads.first).not_to eq(@scheduler.thread)
|
|
361
|
-
|
|
362
|
-
sleep 1.4
|
|
363
|
-
|
|
364
|
-
expect(job.threads.size).to eq(0)
|
|
365
|
-
end
|
|
366
|
-
end
|
|
367
|
-
|
|
368
|
-
context ':allow_overlapping / :allow_overlap / :overlap' do
|
|
369
|
-
|
|
370
|
-
context 'default (:overlap => true)' do
|
|
371
|
-
|
|
372
|
-
it 'lets a job overlap itself' do
|
|
373
|
-
|
|
374
|
-
job =
|
|
375
|
-
@scheduler.every('0.3', :job => true) do
|
|
376
|
-
sleep(5)
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
sleep 3
|
|
380
|
-
|
|
381
|
-
expect(job.threads.size).to be > 1
|
|
382
|
-
end
|
|
383
|
-
end
|
|
384
|
-
|
|
385
|
-
context 'when :overlap => false' do
|
|
386
|
-
|
|
387
|
-
it 'prevents a job from overlapping itself' do
|
|
388
|
-
|
|
389
|
-
job =
|
|
390
|
-
@scheduler.every('0.3', :job => true, :overlap => false) do
|
|
391
|
-
sleep(5)
|
|
392
|
-
end
|
|
393
|
-
|
|
394
|
-
sleep 3
|
|
395
|
-
|
|
396
|
-
expect(job.threads.size).to eq(1)
|
|
397
|
-
end
|
|
398
|
-
end
|
|
399
|
-
end
|
|
400
|
-
|
|
401
|
-
context ':mutex' do
|
|
402
|
-
|
|
403
|
-
context ':mutex => "mutex_name"' do
|
|
404
|
-
|
|
405
|
-
it 'prevents concurrent executions' do
|
|
406
|
-
|
|
407
|
-
j0 =
|
|
408
|
-
@scheduler.in('0s', :job => true, :mutex => 'vladivostok') do
|
|
409
|
-
sleep(3)
|
|
410
|
-
end
|
|
411
|
-
j1 =
|
|
412
|
-
@scheduler.in('0s', :job => true, :mutex => 'vladivostok') do
|
|
413
|
-
sleep(3)
|
|
414
|
-
end
|
|
415
|
-
|
|
416
|
-
sleep 0.7
|
|
417
|
-
|
|
418
|
-
if j0.threads.any?
|
|
419
|
-
expect(j0.threads.size).to eq(1)
|
|
420
|
-
expect(j1.threads.size).to eq(0)
|
|
421
|
-
else
|
|
422
|
-
expect(j0.threads.size).to eq(0)
|
|
423
|
-
expect(j1.threads.size).to eq(1)
|
|
424
|
-
end
|
|
425
|
-
|
|
426
|
-
expect(@scheduler.mutexes.keys).to eq(%w[ vladivostok ])
|
|
427
|
-
end
|
|
428
|
-
end
|
|
429
|
-
|
|
430
|
-
context ':mutex => mutex_instance' do
|
|
431
|
-
|
|
432
|
-
it 'prevents concurrent executions' do
|
|
433
|
-
|
|
434
|
-
m = Mutex.new
|
|
435
|
-
|
|
436
|
-
j0 = @scheduler.in('0s', :job => true, :mutex => m) { sleep(3) }
|
|
437
|
-
j1 = @scheduler.in('0s', :job => true, :mutex => m) { sleep(3) }
|
|
438
|
-
|
|
439
|
-
sleep 0.7
|
|
440
|
-
|
|
441
|
-
if j0.threads.any?
|
|
442
|
-
expect(j0.threads.size).to eq(1)
|
|
443
|
-
expect(j1.threads.size).to eq(0)
|
|
444
|
-
else
|
|
445
|
-
expect(j0.threads.size).to eq(0)
|
|
446
|
-
expect(j1.threads.size).to eq(1)
|
|
447
|
-
end
|
|
448
|
-
|
|
449
|
-
expect(@scheduler.mutexes.keys).to eq([])
|
|
450
|
-
end
|
|
451
|
-
end
|
|
452
|
-
|
|
453
|
-
context ':mutex => [ array_of_mutex_names_or_instances ]' do
|
|
454
|
-
|
|
455
|
-
it 'prevents concurrent executions' do
|
|
456
|
-
|
|
457
|
-
j0 =
|
|
458
|
-
@scheduler.in('0s', :job => true, :mutex => %w[ a b ]) do
|
|
459
|
-
sleep(3)
|
|
460
|
-
end
|
|
461
|
-
j1 =
|
|
462
|
-
@scheduler.in('0s', :job => true, :mutex => %w[ a b ]) do
|
|
463
|
-
sleep(3)
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
sleep 0.7
|
|
467
|
-
|
|
468
|
-
if j0.threads.any?
|
|
469
|
-
expect(j0.threads.size).to eq(1)
|
|
470
|
-
expect(j1.threads.size).to eq(0)
|
|
471
|
-
else
|
|
472
|
-
expect(j0.threads.size).to eq(0)
|
|
473
|
-
expect(j1.threads.size).to eq(1)
|
|
474
|
-
end
|
|
475
|
-
|
|
476
|
-
expect(@scheduler.mutexes.keys.sort).to eq(%w[ a b ])
|
|
477
|
-
end
|
|
478
|
-
end
|
|
479
|
-
end
|
|
480
|
-
|
|
481
|
-
context ':timeout => duration_or_point_in_time' do
|
|
482
|
-
|
|
483
|
-
it 'interrupts the job it is stashed to (duration)' do
|
|
484
|
-
|
|
485
|
-
counter = 0
|
|
486
|
-
toe = nil
|
|
487
|
-
|
|
488
|
-
job =
|
|
489
|
-
@scheduler.schedule_in '0s', :timeout => '1s' do
|
|
490
|
-
begin
|
|
491
|
-
counter = counter + 1
|
|
492
|
-
sleep 1.5
|
|
493
|
-
counter = counter + 1
|
|
494
|
-
rescue Rufus::Scheduler::TimeoutError => e
|
|
495
|
-
toe = e
|
|
496
|
-
end
|
|
497
|
-
end
|
|
498
|
-
|
|
499
|
-
sleep(3)
|
|
500
|
-
|
|
501
|
-
expect(counter).to eq(1)
|
|
502
|
-
expect(toe.class).to eq(Rufus::Scheduler::TimeoutError)
|
|
503
|
-
end
|
|
504
|
-
|
|
505
|
-
it 'interrupts the job it is stashed to (point in time)' do
|
|
506
|
-
|
|
507
|
-
counter = 0
|
|
508
|
-
|
|
509
|
-
job =
|
|
510
|
-
@scheduler.schedule_in '0s', :timeout => Time.now + 1 do
|
|
511
|
-
begin
|
|
512
|
-
counter = counter + 1
|
|
513
|
-
sleep 1.5
|
|
514
|
-
counter = counter + 1
|
|
515
|
-
rescue Rufus::Scheduler::TimeoutError => e
|
|
516
|
-
end
|
|
517
|
-
end
|
|
518
|
-
|
|
519
|
-
sleep(3)
|
|
520
|
-
|
|
521
|
-
expect(counter).to eq(1)
|
|
522
|
-
end
|
|
523
|
-
|
|
524
|
-
it 'starts timing when the job enters successfully all its mutexes' do
|
|
525
|
-
|
|
526
|
-
t0, t1, t2 = nil
|
|
527
|
-
|
|
528
|
-
@scheduler.schedule_in '0s', :mutex => 'a' do
|
|
529
|
-
sleep 1
|
|
530
|
-
t0 = Time.now
|
|
531
|
-
end
|
|
532
|
-
|
|
533
|
-
job =
|
|
534
|
-
@scheduler.schedule_in '0.5s', :mutex => 'a', :timeout => '1s' do
|
|
535
|
-
begin
|
|
536
|
-
t1 = Time.now
|
|
537
|
-
sleep 2
|
|
538
|
-
rescue Rufus::Scheduler::TimeoutError => e
|
|
539
|
-
t2 = Time.now
|
|
540
|
-
end
|
|
541
|
-
end
|
|
542
|
-
|
|
543
|
-
sleep 3
|
|
544
|
-
|
|
545
|
-
expect(t0).to be <= t1
|
|
546
|
-
|
|
547
|
-
d = t2 - t1
|
|
548
|
-
expect(d).to be >= 1.0
|
|
549
|
-
expect(d).to be < 1.5
|
|
550
|
-
end
|
|
551
|
-
|
|
552
|
-
it 'emits the timeout information to $stderr (default #on_error)' do
|
|
553
|
-
|
|
554
|
-
@scheduler.every('1s', :timeout => '0.5s') do
|
|
555
|
-
sleep 0.9
|
|
556
|
-
end
|
|
557
|
-
|
|
558
|
-
sleep 2
|
|
559
|
-
|
|
560
|
-
expect($stderr.string).to match(/Rufus::Scheduler::TimeoutError/)
|
|
561
|
-
end
|
|
562
|
-
|
|
563
|
-
it 'does not prevent a repeat job from recurring' do
|
|
564
|
-
|
|
565
|
-
counter = 0
|
|
566
|
-
|
|
567
|
-
@scheduler.every('1s', :timeout => '0.5s') do
|
|
568
|
-
counter = counter + 1
|
|
569
|
-
sleep 0.9
|
|
570
|
-
end
|
|
571
|
-
|
|
572
|
-
sleep 3
|
|
573
|
-
|
|
574
|
-
expect(counter).to be > 1
|
|
575
|
-
end
|
|
576
|
-
end
|
|
577
|
-
|
|
578
|
-
context 'work time' do
|
|
579
|
-
|
|
580
|
-
describe '#last_work_time' do
|
|
581
|
-
|
|
582
|
-
it 'starts at 0' do
|
|
583
|
-
|
|
584
|
-
job = @scheduler.schedule_every '5m' do; end
|
|
585
|
-
|
|
586
|
-
expect(job.last_work_time).to eq(0.0)
|
|
587
|
-
end
|
|
588
|
-
|
|
589
|
-
it 'keeps track of how long the work was upon last trigger' do
|
|
590
|
-
|
|
591
|
-
job =
|
|
592
|
-
@scheduler.schedule_in '0.5s' do
|
|
593
|
-
sleep 0.7
|
|
594
|
-
end
|
|
595
|
-
|
|
596
|
-
sleep 2
|
|
597
|
-
|
|
598
|
-
expect(job.last_work_time).to be >= 0.7
|
|
599
|
-
expect(job.last_work_time).to be < 0.8
|
|
600
|
-
end
|
|
601
|
-
end
|
|
602
|
-
|
|
603
|
-
describe '#mean_work_time' do
|
|
604
|
-
|
|
605
|
-
it 'starts at 0' do
|
|
606
|
-
|
|
607
|
-
job = @scheduler.schedule_every '5m' do; end
|
|
608
|
-
|
|
609
|
-
expect(job.mean_work_time).to eq(0.0)
|
|
610
|
-
end
|
|
611
|
-
|
|
612
|
-
it 'gathers work times and computes the mean' do
|
|
613
|
-
|
|
614
|
-
job =
|
|
615
|
-
@scheduler.schedule_every '0.5s' do |j|
|
|
616
|
-
#p j.last_work_time
|
|
617
|
-
#p j.mean_work_time
|
|
618
|
-
sleep 0.01 * (j.count + 1)
|
|
619
|
-
end
|
|
620
|
-
|
|
621
|
-
sleep 4.6
|
|
622
|
-
|
|
623
|
-
expect(job.last_work_time).to be >= 0.08
|
|
624
|
-
expect(job.last_work_time).to be < 0.099
|
|
625
|
-
expect(job.mean_work_time).to be > 0.05
|
|
626
|
-
expect(job.mean_work_time).to be < 0.06
|
|
627
|
-
end
|
|
628
|
-
end
|
|
629
|
-
end
|
|
630
|
-
end
|
|
631
|
-
|
data/spec/lockfile_spec.rb
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#
|
|
3
|
-
# Specifying rufus-scheduler
|
|
4
|
-
#
|
|
5
|
-
# Tue Aug 13 05:58:48 JST 2013
|
|
6
|
-
#
|
|
7
|
-
|
|
8
|
-
require 'spec_helper'
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
describe Rufus::Scheduler do
|
|
12
|
-
|
|
13
|
-
after :each do
|
|
14
|
-
|
|
15
|
-
FileUtils.rm_f('.rufus-scheduler.lock')
|
|
16
|
-
FileUtils.rm_f('lock.txt')
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
context ':lockfile => ".rufus-scheduler.lock"' do
|
|
20
|
-
|
|
21
|
-
it 'writes down a .rufus-scheduler.lock file' do
|
|
22
|
-
|
|
23
|
-
s = Rufus::Scheduler.new :lockfile => '.rufus-scheduler.lock'
|
|
24
|
-
|
|
25
|
-
line = File.read('.rufus-scheduler.lock')
|
|
26
|
-
|
|
27
|
-
#p line
|
|
28
|
-
expect(line).to match(/pid: #{$$}/)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it '"flocks" the lock file' do
|
|
32
|
-
|
|
33
|
-
s = Rufus::Scheduler.new :lockfile => '.rufus-scheduler.lock'
|
|
34
|
-
|
|
35
|
-
f = File.new('.rufus-scheduler.lock', 'a')
|
|
36
|
-
|
|
37
|
-
expect(f.flock(File::LOCK_NB | File::LOCK_EX)).to eq(false)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
it 'prevents newer schedulers from starting' do
|
|
41
|
-
|
|
42
|
-
s0 = Rufus::Scheduler.new :lockfile => '.rufus-scheduler.lock'
|
|
43
|
-
s1 = Rufus::Scheduler.new :lockfile => '.rufus-scheduler.lock'
|
|
44
|
-
|
|
45
|
-
expect(s0.started_at).not_to eq(nil)
|
|
46
|
-
expect(s1.started_at).to eq(nil)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it 'releases the lockfile when shutting down' do
|
|
50
|
-
|
|
51
|
-
s = Rufus::Scheduler.new :lockfile => '.rufus-scheduler.lock'
|
|
52
|
-
|
|
53
|
-
s.shutdown(:kill)
|
|
54
|
-
|
|
55
|
-
f = File.new('.rufus-scheduler.lock', 'a')
|
|
56
|
-
|
|
57
|
-
expect(f.flock(File::LOCK_NB | File::LOCK_EX)).to eq(0)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|