rufus-scheduler 2.0.24 → 3.0.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 +6 -0
- data/CREDITS.txt +4 -0
- data/README.md +1064 -0
- data/Rakefile +1 -4
- data/TODO.txt +145 -55
- data/lib/rufus/scheduler.rb +502 -26
- data/lib/rufus/{sc → scheduler}/cronline.rb +46 -17
- data/lib/rufus/{sc/version.rb → scheduler/job_array.rb} +56 -4
- data/lib/rufus/scheduler/jobs.rb +548 -0
- data/lib/rufus/scheduler/util.rb +318 -0
- data/rufus-scheduler.gemspec +30 -4
- data/spec/cronline_spec.rb +29 -8
- data/spec/error_spec.rb +116 -0
- data/spec/job_array_spec.rb +39 -0
- data/spec/job_at_spec.rb +58 -0
- data/spec/job_cron_spec.rb +67 -0
- data/spec/job_every_spec.rb +71 -0
- data/spec/job_in_spec.rb +20 -0
- data/spec/job_interval_spec.rb +68 -0
- data/spec/job_repeat_spec.rb +308 -0
- data/spec/job_spec.rb +387 -115
- data/spec/lockfile_spec.rb +61 -0
- data/spec/parse_spec.rb +203 -0
- data/spec/schedule_at_spec.rb +129 -0
- data/spec/schedule_cron_spec.rb +66 -0
- data/spec/schedule_every_spec.rb +109 -0
- data/spec/schedule_in_spec.rb +80 -0
- data/spec/schedule_interval_spec.rb +128 -0
- data/spec/scheduler_spec.rb +831 -124
- data/spec/spec_helper.rb +65 -0
- data/spec/threads_spec.rb +75 -0
- metadata +64 -59
- data/README.rdoc +0 -661
- data/lib/rufus/otime.rb +0 -3
- data/lib/rufus/sc/jobqueues.rb +0 -160
- data/lib/rufus/sc/jobs.rb +0 -471
- data/lib/rufus/sc/rtime.rb +0 -363
- data/lib/rufus/sc/scheduler.rb +0 -636
- data/spec/at_in_spec.rb +0 -47
- data/spec/at_spec.rb +0 -125
- data/spec/blocking_spec.rb +0 -64
- data/spec/cron_spec.rb +0 -134
- data/spec/every_spec.rb +0 -304
- data/spec/exception_spec.rb +0 -113
- data/spec/in_spec.rb +0 -150
- data/spec/mutex_spec.rb +0 -159
- data/spec/rtime_spec.rb +0 -137
- data/spec/schedulable_spec.rb +0 -97
- data/spec/spec_base.rb +0 -87
- data/spec/stress_schedule_unschedule_spec.rb +0 -159
- data/spec/timeout_spec.rb +0 -148
- data/test/kjw.rb +0 -113
- data/test/t.rb +0 -20
data/spec/error_spec.rb
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Specifying rufus-scheduler
|
4
|
+
#
|
5
|
+
# Fri Aug 9 07:10:18 JST 2013
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe Rufus::Scheduler do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
|
15
|
+
@taoe = Thread.abort_on_exception
|
16
|
+
Thread.abort_on_exception = false
|
17
|
+
|
18
|
+
@ose = $stderr
|
19
|
+
$stderr = StringIO.new
|
20
|
+
|
21
|
+
@scheduler = Rufus::Scheduler.new
|
22
|
+
end
|
23
|
+
|
24
|
+
after :each do
|
25
|
+
|
26
|
+
@scheduler.shutdown
|
27
|
+
|
28
|
+
Thread.abort_on_exception = @taoe
|
29
|
+
|
30
|
+
$stderr = @ose
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'error in block' do
|
34
|
+
|
35
|
+
it 'intercepts the error and describes it on $stderr' do
|
36
|
+
|
37
|
+
counter = 0
|
38
|
+
|
39
|
+
@scheduler.every('0.5s') do
|
40
|
+
counter += 1
|
41
|
+
fail 'argh'
|
42
|
+
end
|
43
|
+
|
44
|
+
sleep 2
|
45
|
+
|
46
|
+
counter.should > 2
|
47
|
+
$stderr.string.should match(/argh/)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'error in callable' do
|
52
|
+
|
53
|
+
class MyFailingHandler
|
54
|
+
attr_reader :counter
|
55
|
+
def initialize
|
56
|
+
@counter = 0
|
57
|
+
end
|
58
|
+
def call(job, time)
|
59
|
+
@counter = @counter + 1
|
60
|
+
fail 'ouch'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'intercepts the error and describes it on $stderr' do
|
65
|
+
|
66
|
+
mfh = MyFailingHandler.new
|
67
|
+
|
68
|
+
@scheduler.every('0.5s', mfh)
|
69
|
+
|
70
|
+
sleep 2
|
71
|
+
|
72
|
+
mfh.counter.should > 2
|
73
|
+
$stderr.string.should match(/ouch/)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'Rufus::Scheduler#stderr=' do
|
78
|
+
|
79
|
+
it 'lets divert error information to custom files' do
|
80
|
+
|
81
|
+
@scheduler.stderr = StringIO.new
|
82
|
+
|
83
|
+
@scheduler.in('0s') do
|
84
|
+
fail 'miserably'
|
85
|
+
end
|
86
|
+
|
87
|
+
sleep 0.5
|
88
|
+
|
89
|
+
@scheduler.stderr.string.should match(/intercepted an error/)
|
90
|
+
@scheduler.stderr.string.should match(/miserably/)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'Rufus::Scheduler#on_error(&block)' do
|
95
|
+
|
96
|
+
it 'intercepts all StandardError instances' do
|
97
|
+
|
98
|
+
$message = nil
|
99
|
+
|
100
|
+
def @scheduler.on_error(job, err)
|
101
|
+
$message = "#{job.class} #{job.original} #{err.message}"
|
102
|
+
rescue
|
103
|
+
p $!
|
104
|
+
end
|
105
|
+
|
106
|
+
@scheduler.in('0s') do
|
107
|
+
fail 'miserably'
|
108
|
+
end
|
109
|
+
|
110
|
+
sleep 0.5
|
111
|
+
|
112
|
+
$message.should == 'Rufus::Scheduler::InJob 0s miserably'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
@@ -0,0 +1,39 @@
|
|
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::JobArray do
|
12
|
+
|
13
|
+
class DummyJob < Struct.new(:id, :next_time); end
|
14
|
+
|
15
|
+
before(:each) do
|
16
|
+
@array = Rufus::Scheduler::JobArray.new
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#push' do
|
20
|
+
|
21
|
+
it 'pushes jobs' do
|
22
|
+
|
23
|
+
@array.push(DummyJob.new('a', Time.local(0)))
|
24
|
+
|
25
|
+
@array.to_a.collect(&:id).should == %w[ a ]
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'pushes and remove duplicates' do
|
29
|
+
|
30
|
+
j = DummyJob.new('a', Time.local(0))
|
31
|
+
|
32
|
+
@array.push(j)
|
33
|
+
@array.push(j)
|
34
|
+
|
35
|
+
@array.to_a.collect(&:id).should == %w[ a ]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
data/spec/job_at_spec.rb
ADDED
@@ -0,0 +1,58 @@
|
|
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::AtJob do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@scheduler = Rufus::Scheduler.new
|
15
|
+
end
|
16
|
+
after :each do
|
17
|
+
@scheduler.shutdown
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#unschedule' do
|
21
|
+
|
22
|
+
it 'unschedules the job' do
|
23
|
+
|
24
|
+
job = @scheduler.at(Time.now + 3600, :job => true) do
|
25
|
+
end
|
26
|
+
|
27
|
+
job.unschedule
|
28
|
+
|
29
|
+
sleep 0.4
|
30
|
+
|
31
|
+
@scheduler.jobs.size.should == 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#scheduled_at' do
|
36
|
+
|
37
|
+
it 'returns the Time at which the job got scheduled' do
|
38
|
+
|
39
|
+
job = @scheduler.schedule_at((t = Time.now) + 3600) {}
|
40
|
+
|
41
|
+
job.scheduled_at.to_i.should >= t.to_i - 1
|
42
|
+
job.scheduled_at.to_i.should <= t.to_i + 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#time' do
|
47
|
+
|
48
|
+
it 'returns the time at which the job will trigger' do
|
49
|
+
|
50
|
+
t = Time.now + 3600
|
51
|
+
|
52
|
+
job = @scheduler.schedule_at t do; end
|
53
|
+
|
54
|
+
job.time.should == t
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,67 @@
|
|
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::CronJob do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@scheduler = Rufus::Scheduler.new
|
15
|
+
end
|
16
|
+
after :each do
|
17
|
+
@scheduler.shutdown
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'normal' do
|
21
|
+
|
22
|
+
it 'triggers near the zero second' do
|
23
|
+
|
24
|
+
job = @scheduler.schedule_cron '* * * * *' do; end
|
25
|
+
|
26
|
+
sleep_until_next_minute
|
27
|
+
|
28
|
+
(job.last_time.to_i % 10).should == 0
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#context 'sub-minute' do
|
33
|
+
#
|
34
|
+
# it 'triggers near the zero second' do
|
35
|
+
#
|
36
|
+
# job = @scheduler.schedule_cron '* * * * * *' do; end
|
37
|
+
#
|
38
|
+
# sleep 1.5
|
39
|
+
#
|
40
|
+
# p job.last_time
|
41
|
+
# p job.last_time.to_f
|
42
|
+
# end
|
43
|
+
#end
|
44
|
+
|
45
|
+
context 'first_at/in' do
|
46
|
+
|
47
|
+
it 'does not trigger before first_at is reached' do
|
48
|
+
|
49
|
+
t = Time.now
|
50
|
+
|
51
|
+
job =
|
52
|
+
@scheduler.schedule_cron '* * * * * *', :first_in => '3s' do
|
53
|
+
triggered = Time.now
|
54
|
+
end
|
55
|
+
|
56
|
+
sleep 1
|
57
|
+
|
58
|
+
#p [ t, t.to_f ]
|
59
|
+
#p [ job.last_time, job.last_time.to_f ]
|
60
|
+
#p [ job.first_at, job.first_at.to_f ]
|
61
|
+
|
62
|
+
job.first_at.should be_within_1s_of(t + 3)
|
63
|
+
job.last_time.should == nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,71 @@
|
|
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::EveryJob do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@scheduler = Rufus::Scheduler.new
|
15
|
+
end
|
16
|
+
after :each do
|
17
|
+
@scheduler.shutdown
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'triggers as expected' do
|
21
|
+
|
22
|
+
counter = 0
|
23
|
+
|
24
|
+
@scheduler.every '1s' do
|
25
|
+
counter = counter + 1
|
26
|
+
end
|
27
|
+
|
28
|
+
sleep 3.5
|
29
|
+
|
30
|
+
[ 2, 3 ].should include(counter)
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'first_at/in' do
|
34
|
+
|
35
|
+
it 'triggers for the first time at first_at' do
|
36
|
+
|
37
|
+
t = Time.now
|
38
|
+
|
39
|
+
job = @scheduler.schedule_every '3s', :first_in => '1s' do; end
|
40
|
+
|
41
|
+
sleep 2
|
42
|
+
|
43
|
+
#p [ t, t.to_f ]
|
44
|
+
#p [ job.last_time, job.last_time.to_f ]
|
45
|
+
#p [ job.first_at, job.first_at.to_f ]
|
46
|
+
|
47
|
+
job.first_at.should be_within_1s_of(t + 2)
|
48
|
+
job.last_time.should be_within_1s_of(job.first_at)
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '#first_at=' do
|
52
|
+
|
53
|
+
it 'alters @next_time' do
|
54
|
+
|
55
|
+
job = @scheduler.schedule_every '3s', :first_in => '10s' do; end
|
56
|
+
|
57
|
+
fa0 = job.first_at
|
58
|
+
nt0 = job.next_time
|
59
|
+
|
60
|
+
job.first_at = Time.now + 3
|
61
|
+
|
62
|
+
fa1 = job.first_at
|
63
|
+
nt1 = job.next_time
|
64
|
+
|
65
|
+
nt0.should == fa0
|
66
|
+
nt1.should == fa1
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
data/spec/job_in_spec.rb
ADDED
@@ -0,0 +1,20 @@
|
|
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::InJob do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@scheduler = Rufus::Scheduler.new
|
15
|
+
end
|
16
|
+
after :each do
|
17
|
+
@scheduler.shutdown
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,68 @@
|
|
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::IntervalJob do
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
@scheduler = Rufus::Scheduler.new
|
15
|
+
end
|
16
|
+
after :each do
|
17
|
+
@scheduler.shutdown
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#interval' do
|
21
|
+
|
22
|
+
it 'returns the scheduled interval' do
|
23
|
+
|
24
|
+
job = @scheduler.schedule_interval('1h') do; end
|
25
|
+
|
26
|
+
job.interval.should == 3600
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'first_at/in' do
|
31
|
+
|
32
|
+
it 'triggers for the first time at first_at' do
|
33
|
+
|
34
|
+
t = Time.now
|
35
|
+
|
36
|
+
job = @scheduler.schedule_interval '3s', :first_in => '1s' do; end
|
37
|
+
|
38
|
+
sleep 2
|
39
|
+
|
40
|
+
#p [ t, t.to_f ]
|
41
|
+
#p [ job.last_time, job.last_time.to_f ]
|
42
|
+
#p [ job.first_at, job.first_at.to_f ]
|
43
|
+
|
44
|
+
job.first_at.should be_within_1s_of(t + 2)
|
45
|
+
job.last_time.should be_within_1s_of(job.first_at)
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#first_at=' do
|
49
|
+
|
50
|
+
it 'alters @next_time' do
|
51
|
+
|
52
|
+
job = @scheduler.schedule_interval '3s', :first_in => '10s' do; end
|
53
|
+
|
54
|
+
fa0 = job.first_at
|
55
|
+
nt0 = job.next_time
|
56
|
+
|
57
|
+
job.first_at = Time.now + 3
|
58
|
+
|
59
|
+
fa1 = job.first_at
|
60
|
+
nt1 = job.next_time
|
61
|
+
|
62
|
+
nt0.should == fa0
|
63
|
+
nt1.should == fa1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|