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
@@ -0,0 +1,109 @@
|
|
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 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 '#every' do
|
21
|
+
|
22
|
+
it 'adds a job' do
|
23
|
+
|
24
|
+
@scheduler.every(10) do
|
25
|
+
end
|
26
|
+
|
27
|
+
@scheduler.jobs.size.should == 1
|
28
|
+
@scheduler.jobs.first.class.should == Rufus::Scheduler::EveryJob
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'triggers a job (2 times)' do
|
32
|
+
|
33
|
+
counter = 0
|
34
|
+
|
35
|
+
@scheduler.every(0.4) do
|
36
|
+
counter += 1
|
37
|
+
end
|
38
|
+
|
39
|
+
sleep 2.0
|
40
|
+
|
41
|
+
counter.should > 2
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'does not remove the job after execution' do
|
45
|
+
|
46
|
+
@scheduler.every(0.4) do
|
47
|
+
end
|
48
|
+
|
49
|
+
sleep 0.9
|
50
|
+
|
51
|
+
@scheduler.jobs.size.should == 1
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'raises on negative frequencies' do
|
55
|
+
|
56
|
+
lambda {
|
57
|
+
@scheduler.every(-1) do
|
58
|
+
end
|
59
|
+
}.should raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'raises on zero frequencies' do
|
63
|
+
|
64
|
+
lambda {
|
65
|
+
@scheduler.every(0) do
|
66
|
+
end
|
67
|
+
}.should raise_error(ArgumentError)
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'does not reschedule if the job was unscheduled' do
|
71
|
+
|
72
|
+
counter = 0
|
73
|
+
|
74
|
+
job =
|
75
|
+
@scheduler.schedule_every '0.5s' do
|
76
|
+
counter = counter + 1
|
77
|
+
end
|
78
|
+
|
79
|
+
sleep 1.6
|
80
|
+
|
81
|
+
job.unschedule
|
82
|
+
c = counter
|
83
|
+
|
84
|
+
sleep 1.6
|
85
|
+
|
86
|
+
counter.should == c
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'raises if the job frequency is higher than the scheduler frequency' do
|
90
|
+
|
91
|
+
@scheduler.frequency = 10
|
92
|
+
|
93
|
+
lambda {
|
94
|
+
@scheduler.every '1s' do; end
|
95
|
+
}.should raise_error(ArgumentError)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe '#schedule_every' do
|
100
|
+
|
101
|
+
it 'accepts a duration string' do
|
102
|
+
|
103
|
+
job = @scheduler.schedule_every('1h') do; end
|
104
|
+
|
105
|
+
job.frequency.should == 3600.0
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
@@ -0,0 +1,80 @@
|
|
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 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 '#in' do
|
21
|
+
|
22
|
+
it 'adds a job' do
|
23
|
+
|
24
|
+
@scheduler.in(3600) do
|
25
|
+
end
|
26
|
+
|
27
|
+
@scheduler.jobs.size.should == 1
|
28
|
+
@scheduler.jobs.first.class.should == Rufus::Scheduler::InJob
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'triggers a job' do
|
32
|
+
|
33
|
+
a = false
|
34
|
+
|
35
|
+
@scheduler.in(0.4) do
|
36
|
+
a = true
|
37
|
+
end
|
38
|
+
|
39
|
+
sleep 0.9
|
40
|
+
|
41
|
+
a.should == true
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'removes the job after execution' do
|
45
|
+
|
46
|
+
@scheduler.in(0.4) do
|
47
|
+
end
|
48
|
+
|
49
|
+
sleep 0.700
|
50
|
+
|
51
|
+
@scheduler.jobs.size.should == 0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#schedule_in' do
|
56
|
+
|
57
|
+
it 'accepts a number' do
|
58
|
+
|
59
|
+
job = @scheduler.schedule_in(3600) {}
|
60
|
+
|
61
|
+
job.original.should == 3600
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'accepts a duration string' do
|
65
|
+
|
66
|
+
job = @scheduler.schedule_in('1h') {}
|
67
|
+
|
68
|
+
job.original.should == '1h'
|
69
|
+
job.time.should >= job.scheduled_at + 3509
|
70
|
+
job.time.should <= job.scheduled_at + 3601
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'accepts an ActiveSupport .from_now thinggy'
|
74
|
+
#
|
75
|
+
# schedule_in(2.days.from_now)
|
76
|
+
#
|
77
|
+
# that'd simply require "in" to be a bit like "at"...
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
@@ -0,0 +1,128 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Specifying rufus-scheduler
|
4
|
+
#
|
5
|
+
# Wed Aug 7 06:20:55 JST 2013
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'spec_helper'
|
9
|
+
|
10
|
+
|
11
|
+
describe Rufus::Scheduler 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 'adds a job' do
|
23
|
+
|
24
|
+
@scheduler.interval(10) do
|
25
|
+
end
|
26
|
+
|
27
|
+
@scheduler.jobs.size.should == 1
|
28
|
+
@scheduler.jobs.first.class.should == Rufus::Scheduler::IntervalJob
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'triggers a job (2 times)' do
|
32
|
+
|
33
|
+
counter = 0
|
34
|
+
|
35
|
+
@scheduler.interval(0.4) do
|
36
|
+
counter += 1
|
37
|
+
end
|
38
|
+
|
39
|
+
sleep 2.0
|
40
|
+
|
41
|
+
counter.should > 2
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'triggers, but reschedules after the trigger execution' do
|
45
|
+
|
46
|
+
chronos = []
|
47
|
+
|
48
|
+
@scheduler.interval(0.4) do
|
49
|
+
now = Time.now
|
50
|
+
last, delta = chronos.last
|
51
|
+
chronos << [ now, last ? now - last : nil ]
|
52
|
+
sleep 0.5
|
53
|
+
end
|
54
|
+
|
55
|
+
t = Time.now
|
56
|
+
sleep 0.1 while chronos.size < 4 && Time.now < t + 5
|
57
|
+
|
58
|
+
chronos.size.should == 4
|
59
|
+
|
60
|
+
deltas = chronos.collect(&:last).compact
|
61
|
+
|
62
|
+
#pp chronos
|
63
|
+
#pp deltas
|
64
|
+
|
65
|
+
deltas.each do |d|
|
66
|
+
d.should >= 0.9
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'does not reschedule if the job was unscheduled' do
|
71
|
+
|
72
|
+
counter = 0
|
73
|
+
|
74
|
+
job =
|
75
|
+
@scheduler.schedule_interval '0.5s' do
|
76
|
+
counter = counter + 1
|
77
|
+
end
|
78
|
+
|
79
|
+
sleep 1.6
|
80
|
+
|
81
|
+
@scheduler.jobs(:all).size.should == 1
|
82
|
+
|
83
|
+
job.unschedule
|
84
|
+
c = counter
|
85
|
+
|
86
|
+
sleep 1.6
|
87
|
+
|
88
|
+
counter.should == c
|
89
|
+
@scheduler.jobs(:all).size.should == 0
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'raises on negative intervals' do
|
93
|
+
|
94
|
+
lambda {
|
95
|
+
@scheduler.interval(-1) do
|
96
|
+
end
|
97
|
+
}.should raise_error(ArgumentError)
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'raises on zero intervals' do
|
101
|
+
|
102
|
+
lambda {
|
103
|
+
@scheduler.interval(0) do
|
104
|
+
end
|
105
|
+
}.should raise_error(ArgumentError)
|
106
|
+
end
|
107
|
+
|
108
|
+
#it 'raises if the job frequency is higher than the scheduler frequency' do
|
109
|
+
#
|
110
|
+
# @scheduler.frequency = 10
|
111
|
+
#
|
112
|
+
# lambda {
|
113
|
+
# @scheduler.interval '1s' do; end
|
114
|
+
# }.should raise_error(ArgumentError)
|
115
|
+
#end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe '#schedule_interval' do
|
119
|
+
|
120
|
+
it 'accepts a duration string' do
|
121
|
+
|
122
|
+
job = @scheduler.schedule_interval('1h') do; end
|
123
|
+
|
124
|
+
job.interval.should == 3600
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
data/spec/scheduler_spec.rb
CHANGED
@@ -2,247 +2,954 @@
|
|
2
2
|
#
|
3
3
|
# Specifying rufus-scheduler
|
4
4
|
#
|
5
|
-
#
|
5
|
+
# Wed Apr 17 06:00:59 JST 2013
|
6
6
|
#
|
7
7
|
|
8
|
-
require '
|
8
|
+
require 'spec_helper'
|
9
9
|
|
10
10
|
|
11
|
-
describe
|
11
|
+
describe Rufus::Scheduler do
|
12
12
|
|
13
|
-
|
13
|
+
describe '#initialize' do
|
14
14
|
|
15
|
-
|
15
|
+
it 'starts the scheduler thread' do
|
16
16
|
|
17
|
-
|
18
|
-
s.in('3s') { var = true }
|
17
|
+
scheduler = Rufus::Scheduler.new
|
19
18
|
|
20
|
-
|
19
|
+
t = Thread.list.find { |t|
|
20
|
+
t[:name] == "rufus_scheduler_#{scheduler.object_id}_scheduler"
|
21
|
+
}
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
23
|
+
t[:rufus_scheduler].should == scheduler
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'sets a :rufus_scheduler thread local var' do
|
27
|
+
|
28
|
+
scheduler = Rufus::Scheduler.new
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'accepts a :frequency => integer option' do
|
32
|
+
|
33
|
+
scheduler = Rufus::Scheduler.new(:frequency => 2)
|
34
|
+
|
35
|
+
scheduler.frequency.should == 2
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'accepts a :frequency => "2h1m" option' do
|
39
|
+
|
40
|
+
scheduler = Rufus::Scheduler.new(:frequency => '2h1m')
|
41
|
+
|
42
|
+
scheduler.frequency.should == 3600 * 2 + 60
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'accepts a :thread_name option' do
|
46
|
+
|
47
|
+
scheduler = Rufus::Scheduler.new(:thread_name => 'oliphant')
|
48
|
+
|
49
|
+
t = Thread.list.find { |t| t[:name] == 'oliphant' }
|
50
|
+
|
51
|
+
t[:rufus_scheduler].should == scheduler
|
52
|
+
end
|
53
|
+
|
54
|
+
#it 'accepts a :min_work_threads option' do
|
55
|
+
# scheduler = Rufus::Scheduler.new(:min_work_threads => 9)
|
56
|
+
# scheduler.min_work_threads.should == 9
|
57
|
+
#end
|
58
|
+
|
59
|
+
it 'accepts a :max_work_threads option' do
|
60
|
+
|
61
|
+
scheduler = Rufus::Scheduler.new(:max_work_threads => 9)
|
62
|
+
|
63
|
+
scheduler.max_work_threads.should == 9
|
64
|
+
end
|
25
65
|
end
|
26
66
|
|
27
|
-
|
67
|
+
before :each do
|
68
|
+
@scheduler = Rufus::Scheduler.new
|
69
|
+
end
|
70
|
+
after :each do
|
71
|
+
@scheduler.shutdown
|
72
|
+
end
|
73
|
+
|
74
|
+
describe 'a schedule method' do
|
28
75
|
|
29
|
-
it '
|
76
|
+
it 'passes the job to its block when it triggers' do
|
30
77
|
|
31
|
-
|
78
|
+
j = nil
|
79
|
+
job = @scheduler.schedule_in('0s') { |jj| j = jj }
|
80
|
+
|
81
|
+
sleep 0.4
|
82
|
+
|
83
|
+
j.should == job
|
84
|
+
end
|
32
85
|
|
33
|
-
|
34
|
-
/Rufus::Scheduler::.*Scheduler - \d+\.\d+\.\d+/)
|
86
|
+
it 'passes the trigger time as second block argument' do
|
35
87
|
|
36
|
-
|
88
|
+
t = nil
|
89
|
+
@scheduler.schedule_in('0s') { |jj, tt| t = tt }
|
90
|
+
|
91
|
+
sleep 0.4
|
92
|
+
|
93
|
+
t.class.should == Time
|
94
|
+
end
|
95
|
+
|
96
|
+
class MyHandler
|
97
|
+
attr_reader :counter
|
98
|
+
def initialize
|
99
|
+
@counter = 0
|
100
|
+
end
|
101
|
+
def call(job, time)
|
102
|
+
@counter = @counter + 1
|
103
|
+
end
|
37
104
|
end
|
38
105
|
|
39
|
-
it '
|
106
|
+
it 'accepts a callable object instead of a block' do
|
107
|
+
|
108
|
+
mh = MyHandler.new
|
109
|
+
|
110
|
+
@scheduler.schedule_in('0s', mh)
|
40
111
|
|
41
|
-
|
42
|
-
s.instance_variable_get(:@thread)['name'].should == 'nada'
|
112
|
+
sleep 0.4
|
43
113
|
|
44
|
-
|
114
|
+
mh.counter.should == 1
|
115
|
+
end
|
116
|
+
|
117
|
+
class MyOtherHandler
|
118
|
+
attr_reader :counter
|
119
|
+
def initialize
|
120
|
+
@counter = 0
|
121
|
+
end
|
122
|
+
def call
|
123
|
+
@counter = @counter + 1
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'accepts a callable obj instead of a block (#call with no args)' do
|
128
|
+
|
129
|
+
job = @scheduler.schedule_in('0s', MyOtherHandler.new)
|
130
|
+
|
131
|
+
sleep 0.4
|
132
|
+
|
133
|
+
job.handler.counter.should == 1
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'accepts a class as callable' do
|
137
|
+
|
138
|
+
job =
|
139
|
+
@scheduler.schedule_in('0s', Class.new do
|
140
|
+
attr_reader :value
|
141
|
+
def call
|
142
|
+
@value = 7
|
143
|
+
end
|
144
|
+
end)
|
145
|
+
|
146
|
+
sleep 0.4
|
147
|
+
|
148
|
+
job.handler.value.should == 7
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'raises if the scheduler is shutting down' do
|
152
|
+
|
153
|
+
@scheduler.shutdown
|
154
|
+
|
155
|
+
lambda {
|
156
|
+
@scheduler.in('0s') { puts 'hhhhhhhhhhhello!!' }
|
157
|
+
}.should raise_error(RuntimeError)
|
45
158
|
end
|
46
159
|
end
|
47
160
|
|
48
|
-
|
161
|
+
describe '#in / #at' do
|
162
|
+
|
163
|
+
# scheduler.in(2.hours.from_now) { ... }
|
49
164
|
|
50
|
-
|
165
|
+
it 'accepts point in time and duration indifferently (#in)' do
|
51
166
|
|
52
|
-
|
167
|
+
seen = false
|
53
168
|
|
54
|
-
|
169
|
+
t = Time.now + 1
|
55
170
|
|
56
|
-
|
57
|
-
var.should == nil
|
171
|
+
@scheduler.in(t) { seen = true }
|
58
172
|
|
59
|
-
|
60
|
-
|
173
|
+
sleep 0.1 while seen != true
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'accepts point in time and duration indifferently (#at)' do
|
177
|
+
|
178
|
+
seen = false
|
61
179
|
|
62
|
-
|
63
|
-
var.should == true
|
180
|
+
t = 1
|
64
181
|
|
65
|
-
|
182
|
+
@scheduler.at(t) { seen = true }
|
183
|
+
|
184
|
+
sleep 0.1 while seen != true
|
185
|
+
end
|
66
186
|
end
|
67
187
|
|
68
|
-
|
188
|
+
describe '#schedule' do
|
69
189
|
|
70
|
-
|
71
|
-
|
190
|
+
it 'accepts a duration and schedules an InJob' do
|
191
|
+
|
192
|
+
j = @scheduler.schedule '1s' do; end
|
193
|
+
|
194
|
+
j.class.should == Rufus::Scheduler::InJob
|
195
|
+
j.original.should == '1s'
|
72
196
|
end
|
73
|
-
|
74
|
-
|
197
|
+
|
198
|
+
it 'accepts a point in time and schedules an AtJob' do
|
199
|
+
|
200
|
+
j = @scheduler.schedule '2070/12/24 23:00' do; end
|
201
|
+
|
202
|
+
j.class.should == Rufus::Scheduler::AtJob
|
203
|
+
j.next_time.strftime('%Y %m %d').should == '2070 12 24'
|
75
204
|
end
|
76
205
|
|
77
|
-
|
206
|
+
it 'accepts a cron string and schedules a CronJob' do
|
207
|
+
|
208
|
+
j = @scheduler.schedule '* * * * *' do; end
|
209
|
+
|
210
|
+
j.class.should == Rufus::Scheduler::CronJob
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe '#repeat' do
|
215
|
+
|
216
|
+
it 'accepts a duration and schedules an EveryJob' do
|
217
|
+
|
218
|
+
j = @scheduler.repeat '1s' do; end
|
219
|
+
|
220
|
+
j.class.should == Rufus::Scheduler::EveryJob
|
221
|
+
end
|
222
|
+
|
223
|
+
it 'accepts a cron string and schedules a CronJob' do
|
224
|
+
|
225
|
+
j = @scheduler.repeat '* * * * *' do; end
|
226
|
+
|
227
|
+
j.class.should == Rufus::Scheduler::CronJob
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
describe '#unschedule(job_or_work_id)' do
|
232
|
+
|
233
|
+
it 'accepts job ids' do
|
234
|
+
|
235
|
+
job = @scheduler.schedule_in '10d' do; end
|
236
|
+
|
237
|
+
job.unscheduled_at.should == nil
|
238
|
+
|
239
|
+
@scheduler.unschedule(job.id)
|
240
|
+
|
241
|
+
job.unscheduled_at.should_not == nil
|
242
|
+
end
|
78
243
|
|
79
|
-
|
244
|
+
it 'accepts jobs' do
|
80
245
|
|
81
|
-
|
246
|
+
job = @scheduler.schedule_in '10d' do; end
|
82
247
|
|
83
|
-
|
84
|
-
|
248
|
+
job.unscheduled_at.should == nil
|
249
|
+
|
250
|
+
@scheduler.unschedule(job)
|
251
|
+
|
252
|
+
job.unscheduled_at.should_not == nil
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'carefully unschedules repeat jobs' do
|
256
|
+
|
257
|
+
counter = 0
|
258
|
+
|
259
|
+
job =
|
260
|
+
@scheduler.schedule_every '0.5s' do
|
261
|
+
counter = counter + 1
|
85
262
|
end
|
86
263
|
|
87
|
-
|
264
|
+
sleep 1.5
|
265
|
+
c = counter
|
266
|
+
|
267
|
+
@scheduler.unschedule(job)
|
268
|
+
|
269
|
+
sleep 1.5
|
270
|
+
counter.should == c
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe '#uptime' do
|
275
|
+
|
276
|
+
it 'returns the uptime as a float' do
|
277
|
+
|
278
|
+
@scheduler.uptime.should >= 0.0
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe '#uptime_s' do
|
283
|
+
|
284
|
+
it 'returns the uptime as a human readable string' do
|
285
|
+
|
286
|
+
sleep 1
|
287
|
+
|
288
|
+
@scheduler.uptime_s.should match(/^[12]s\d+$/)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
describe '#join' do
|
293
|
+
|
294
|
+
it 'joins the scheduler thread' do
|
295
|
+
|
296
|
+
t = Thread.new { @scheduler.join; Thread.current['a'] = 'over' }
|
297
|
+
|
298
|
+
t['a'].should == nil
|
299
|
+
|
300
|
+
@scheduler.shutdown
|
301
|
+
|
302
|
+
sleep(1)
|
303
|
+
|
304
|
+
t['a'].should == 'over'
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe '#job(job_id)' do
|
309
|
+
|
310
|
+
it 'returns nil if there is no corresponding Job instance' do
|
311
|
+
|
312
|
+
@scheduler.job('nada').should == nil
|
313
|
+
end
|
314
|
+
|
315
|
+
it 'returns the corresponding Job instance' do
|
316
|
+
|
317
|
+
job_id = @scheduler.in '10d' do; end
|
318
|
+
|
319
|
+
sleep(1) # give it some time to get scheduled
|
320
|
+
|
321
|
+
@scheduler.job(job_id).job_id.should == job_id
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# describe '#find_by_tag(t)' do
|
326
|
+
#
|
327
|
+
# it 'returns an empty list when there are no jobs with the given tag' do
|
328
|
+
#
|
329
|
+
# @scheduler.find_by_tag('nada').should == []
|
330
|
+
# end
|
331
|
+
#
|
332
|
+
# it 'returns all the jobs with the given tag' do
|
333
|
+
#
|
334
|
+
# @scheduler.in '10d', :tag => 't0' do; end
|
335
|
+
# @scheduler.every '2h', :tag => %w[ t0 t1 ] do; end
|
336
|
+
# @scheduler.every '3h' do; end
|
337
|
+
#
|
338
|
+
# @scheduler.find_by_tag('t0').map(&:original).should ==
|
339
|
+
# %w[ 2h 10d ]
|
340
|
+
# @scheduler.find_by_tag('t1').map(&:original).should ==
|
341
|
+
# %w[ 2h ]
|
342
|
+
# @scheduler.find_by_tag('t1', 't0').map(&:original).sort.should ==
|
343
|
+
# %w[ 2h ]
|
344
|
+
# end
|
345
|
+
# end
|
346
|
+
|
347
|
+
describe '#threads' do
|
348
|
+
|
349
|
+
it 'just lists the main thread (scheduler thread) when no job is scheduled' do
|
88
350
|
|
89
|
-
|
351
|
+
@scheduler.threads.should == [ @scheduler.thread ]
|
352
|
+
end
|
90
353
|
|
91
|
-
|
92
|
-
|
354
|
+
it 'lists all the threads a scheduler uses' do
|
355
|
+
|
356
|
+
@scheduler.in '0s' do
|
357
|
+
sleep(2)
|
93
358
|
end
|
94
359
|
|
95
|
-
|
360
|
+
sleep 0.4
|
96
361
|
|
97
|
-
|
362
|
+
@scheduler.threads.size.should == 2
|
363
|
+
end
|
364
|
+
end
|
98
365
|
|
99
|
-
|
100
|
-
|
101
|
-
|
366
|
+
describe '#work_threads(:all)' do
|
367
|
+
|
368
|
+
it 'returns an empty array when the scheduler has not yet done anything' do
|
102
369
|
|
103
|
-
|
370
|
+
@scheduler.work_threads.should == []
|
371
|
+
end
|
104
372
|
|
105
|
-
|
373
|
+
it 'lists all the work threads in the pool' do
|
106
374
|
|
107
|
-
|
108
|
-
|
375
|
+
@scheduler.in '0s' do
|
376
|
+
# nada
|
377
|
+
end
|
378
|
+
@scheduler.in '0s' do
|
379
|
+
sleep(2)
|
109
380
|
end
|
381
|
+
|
382
|
+
sleep 0.6
|
383
|
+
|
384
|
+
@scheduler.work_threads.size.should == 2
|
110
385
|
end
|
386
|
+
end
|
387
|
+
|
388
|
+
describe '#work_threads(:vacant)' do
|
111
389
|
|
112
|
-
|
390
|
+
it 'returns an empty array when the scheduler has not yet done anything' do
|
113
391
|
|
114
|
-
|
392
|
+
@scheduler.work_threads(:vacant).should == []
|
393
|
+
end
|
394
|
+
|
395
|
+
it 'lists all the work threads in the pool' do
|
396
|
+
|
397
|
+
@scheduler.in '0s' do
|
398
|
+
# nada
|
399
|
+
end
|
400
|
+
@scheduler.in '0s' do
|
401
|
+
sleep(2)
|
402
|
+
end
|
115
403
|
|
116
|
-
|
404
|
+
sleep 0.4
|
117
405
|
|
118
|
-
|
119
|
-
|
406
|
+
@scheduler.work_threads(:vacant).size.should == 1
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
describe '#work_threads(:active)' do
|
411
|
+
|
412
|
+
it 'returns [] when there are no jobs running' do
|
413
|
+
|
414
|
+
@scheduler.work_threads(:active).should == []
|
415
|
+
end
|
416
|
+
|
417
|
+
it 'returns the list of threads of the running jobs' do
|
418
|
+
|
419
|
+
job =
|
420
|
+
@scheduler.schedule_in('0s') do
|
421
|
+
sleep 1
|
120
422
|
end
|
121
423
|
|
122
|
-
|
424
|
+
sleep 0.4
|
123
425
|
|
124
|
-
|
426
|
+
@scheduler.work_threads(:active).size.should == 1
|
125
427
|
|
126
|
-
|
428
|
+
t = @scheduler.work_threads(:active).first
|
127
429
|
|
128
|
-
|
430
|
+
t.class.should == Thread
|
431
|
+
t[@scheduler.thread_key].should == true
|
432
|
+
t[:rufus_scheduler_job].should == job
|
433
|
+
t[:rufus_scheduler_time].should_not == nil
|
434
|
+
end
|
129
435
|
|
130
|
-
|
436
|
+
it 'does not return threads from other schedulers' do
|
131
437
|
|
132
|
-
|
133
|
-
($count > c).should == true
|
134
|
-
end
|
438
|
+
scheduler = Rufus::Scheduler.new
|
135
439
|
|
136
|
-
|
440
|
+
job =
|
441
|
+
@scheduler.schedule_in('0s') do
|
442
|
+
sleep(1)
|
443
|
+
end
|
137
444
|
|
138
|
-
|
445
|
+
sleep 0.4
|
446
|
+
|
447
|
+
scheduler.work_threads(:active).should == []
|
448
|
+
|
449
|
+
scheduler.shutdown
|
450
|
+
end
|
451
|
+
end
|
452
|
+
|
453
|
+
#describe '#min_work_threads' do
|
454
|
+
# it 'returns the min job thread count' do
|
455
|
+
# @scheduler.min_work_threads.should == 7
|
456
|
+
# end
|
457
|
+
#end
|
458
|
+
#describe '#min_work_threads=' do
|
459
|
+
# it 'sets the min job thread count' do
|
460
|
+
# @scheduler.min_work_threads = 1
|
461
|
+
# @scheduler.min_work_threads.should == 1
|
462
|
+
# end
|
463
|
+
#end
|
464
|
+
|
465
|
+
describe '#max_work_threads' do
|
466
|
+
|
467
|
+
it 'returns the max job thread count' do
|
468
|
+
|
469
|
+
@scheduler.max_work_threads.should == 35
|
470
|
+
end
|
471
|
+
end
|
139
472
|
|
140
|
-
|
141
|
-
|
473
|
+
describe '#max_work_threads=' do
|
474
|
+
|
475
|
+
it 'sets the max job thread count' do
|
476
|
+
|
477
|
+
@scheduler.max_work_threads = 14
|
478
|
+
|
479
|
+
@scheduler.max_work_threads.should == 14
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
#describe '#kill_all_work_threads' do
|
484
|
+
#
|
485
|
+
# it 'kills all the work threads' do
|
486
|
+
#
|
487
|
+
# @scheduler.in '0s' do; sleep(5); end
|
488
|
+
# @scheduler.in '0s' do; sleep(5); end
|
489
|
+
# @scheduler.in '0s' do; sleep(5); end
|
490
|
+
#
|
491
|
+
# sleep 0.5
|
492
|
+
#
|
493
|
+
# @scheduler.work_threads.size.should == 3
|
494
|
+
#
|
495
|
+
# @scheduler.send(:kill_all_work_threads)
|
496
|
+
#
|
497
|
+
# sleep 0.5
|
498
|
+
#
|
499
|
+
# @scheduler.work_threads.size.should == 0
|
500
|
+
# end
|
501
|
+
#end
|
502
|
+
|
503
|
+
describe '#running_jobs' do
|
504
|
+
|
505
|
+
it 'returns [] when there are no running jobs' do
|
506
|
+
|
507
|
+
@scheduler.running_jobs.should == []
|
508
|
+
end
|
509
|
+
|
510
|
+
it 'returns a list of running Job instances' do
|
511
|
+
|
512
|
+
job =
|
513
|
+
@scheduler.schedule_in('0s') do
|
514
|
+
sleep(1)
|
142
515
|
end
|
143
516
|
|
144
|
-
|
517
|
+
sleep 0.4
|
518
|
+
|
519
|
+
job.running?.should == true
|
520
|
+
@scheduler.running_jobs.should == [ job ]
|
521
|
+
end
|
522
|
+
|
523
|
+
it 'does not return twice the same job' do
|
524
|
+
|
525
|
+
job =
|
526
|
+
@scheduler.schedule_every('0.3s') do
|
527
|
+
sleep(5)
|
528
|
+
end
|
145
529
|
|
146
|
-
|
530
|
+
sleep 1.5
|
147
531
|
|
148
|
-
|
532
|
+
job.running?.should == true
|
533
|
+
@scheduler.running_jobs.should == [ job ]
|
534
|
+
end
|
535
|
+
end
|
149
536
|
|
150
|
-
|
537
|
+
describe '#running_jobs(:tag/:tags => x)' do
|
151
538
|
|
152
|
-
|
539
|
+
it 'returns a list of running jobs filtered by tag' do
|
153
540
|
|
154
|
-
|
155
|
-
|
541
|
+
@scheduler.in '0.1s', :tag => 't0' do
|
542
|
+
sleep 3
|
543
|
+
end
|
544
|
+
@scheduler.in '0.2s', :tag => 't1' do
|
545
|
+
sleep 3
|
156
546
|
end
|
547
|
+
|
548
|
+
sleep 0.4
|
549
|
+
|
550
|
+
@scheduler.running_jobs(:tag => 't0').map(&:original).should ==
|
551
|
+
%w[ 0.1s ]
|
552
|
+
@scheduler.running_jobs(:tag => 't1').map(&:original).should ==
|
553
|
+
%w[ 0.2s ]
|
554
|
+
@scheduler.running_jobs(:tags => %w[ t0 t1 ]).map(&:original).should ==
|
555
|
+
[]
|
157
556
|
end
|
158
557
|
end
|
159
558
|
|
160
|
-
|
559
|
+
#--
|
560
|
+
# management methods
|
561
|
+
#++
|
161
562
|
|
162
|
-
|
163
|
-
|
563
|
+
describe '#shutdown' do
|
564
|
+
|
565
|
+
it 'blanks the uptime' do
|
566
|
+
|
567
|
+
@scheduler.shutdown
|
568
|
+
|
569
|
+
@scheduler.uptime.should == nil
|
164
570
|
end
|
165
|
-
|
166
|
-
|
571
|
+
|
572
|
+
it 'shuts the scheduler down' do
|
573
|
+
|
574
|
+
@scheduler.shutdown
|
575
|
+
|
576
|
+
sleep 0.100
|
577
|
+
sleep 0.400 if RUBY_VERSION < '1.9.0'
|
578
|
+
|
579
|
+
t = Thread.list.find { |t|
|
580
|
+
t[:name] == "rufus_scheduler_#{@scheduler.object_id}"
|
581
|
+
}
|
582
|
+
|
583
|
+
t.should == nil
|
167
584
|
end
|
168
585
|
|
169
|
-
|
586
|
+
it 'has a #stop alias' do
|
170
587
|
|
171
|
-
|
588
|
+
@scheduler.stop
|
172
589
|
|
173
|
-
|
174
|
-
|
590
|
+
@scheduler.uptime.should == nil
|
591
|
+
end
|
175
592
|
|
176
|
-
|
593
|
+
#it 'has a #close alias'
|
594
|
+
end
|
177
595
|
|
178
|
-
|
596
|
+
describe '#shutdown(:wait)' do
|
179
597
|
|
180
|
-
|
598
|
+
it 'shuts down and blocks until all the jobs ended their current runs' do
|
181
599
|
|
182
|
-
|
600
|
+
counter = 0
|
601
|
+
|
602
|
+
@scheduler.in '0s' do
|
603
|
+
sleep 1
|
604
|
+
counter = counter + 1
|
183
605
|
end
|
606
|
+
|
607
|
+
sleep 0.4
|
608
|
+
|
609
|
+
@scheduler.shutdown(:wait)
|
610
|
+
|
611
|
+
counter.should == 1
|
612
|
+
@scheduler.uptime.should == nil
|
613
|
+
@scheduler.running_jobs.should == []
|
614
|
+
@scheduler.threads.should == []
|
184
615
|
end
|
616
|
+
end
|
185
617
|
|
186
|
-
|
618
|
+
describe '#shutdown(:kill)' do
|
187
619
|
|
188
|
-
|
620
|
+
it 'kills all the jobs and then shuts down' do
|
189
621
|
|
190
|
-
|
622
|
+
counter = 0
|
623
|
+
|
624
|
+
@scheduler.in '0s' do
|
625
|
+
sleep 1
|
626
|
+
counter = counter + 1
|
627
|
+
end
|
628
|
+
@scheduler.at Time.now + 0.3 do
|
629
|
+
sleep 1
|
630
|
+
counter = counter + 1
|
191
631
|
end
|
192
632
|
|
193
|
-
|
633
|
+
sleep 0.4
|
634
|
+
|
635
|
+
@scheduler.shutdown(:kill)
|
636
|
+
|
637
|
+
sleep 1.4
|
638
|
+
|
639
|
+
counter.should == 0
|
640
|
+
@scheduler.uptime.should == nil
|
641
|
+
@scheduler.running_jobs.should == []
|
642
|
+
@scheduler.threads.should == []
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
describe '#pause' do
|
647
|
+
|
648
|
+
it 'pauses the scheduler' do
|
649
|
+
|
650
|
+
job = @scheduler.schedule_in '1s' do; end
|
651
|
+
|
652
|
+
@scheduler.pause
|
653
|
+
|
654
|
+
sleep(3)
|
655
|
+
|
656
|
+
job.last_time.should == nil
|
657
|
+
end
|
658
|
+
end
|
659
|
+
|
660
|
+
describe '#resume' do
|
661
|
+
|
662
|
+
it 'works' do
|
663
|
+
|
664
|
+
job = @scheduler.schedule_in '2s' do; end
|
194
665
|
|
195
|
-
|
666
|
+
@scheduler.pause
|
667
|
+
sleep(1)
|
668
|
+
@scheduler.resume
|
669
|
+
sleep(2)
|
196
670
|
|
197
|
-
|
671
|
+
job.last_time.should_not == nil
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
describe '#paused?' do
|
676
|
+
|
677
|
+
it 'returns true if the scheduler is paused' do
|
678
|
+
|
679
|
+
@scheduler.pause
|
680
|
+
@scheduler.paused?.should == true
|
681
|
+
end
|
198
682
|
|
199
|
-
|
683
|
+
it 'returns false if the scheduler is not paused' do
|
684
|
+
|
685
|
+
@scheduler.paused?.should == false
|
686
|
+
|
687
|
+
@scheduler.pause
|
688
|
+
@scheduler.resume
|
689
|
+
|
690
|
+
@scheduler.paused?.should == false
|
691
|
+
end
|
692
|
+
end
|
693
|
+
|
694
|
+
#--
|
695
|
+
# job methods
|
696
|
+
#++
|
697
|
+
|
698
|
+
describe '#jobs' do
|
699
|
+
|
700
|
+
it 'is empty at the beginning' do
|
701
|
+
|
702
|
+
@scheduler.jobs.should == []
|
703
|
+
end
|
704
|
+
|
705
|
+
it 'returns the list of scheduled jobs' do
|
706
|
+
|
707
|
+
@scheduler.in '10d' do; end
|
708
|
+
@scheduler.in '1w' do; end
|
709
|
+
|
710
|
+
sleep(1)
|
711
|
+
|
712
|
+
jobs = @scheduler.jobs
|
713
|
+
|
714
|
+
jobs.collect { |j| j.original }.sort.should == %w[ 10d 1w ]
|
715
|
+
end
|
716
|
+
|
717
|
+
it 'returns all the jobs (even those pending reschedule)' do
|
718
|
+
|
719
|
+
@scheduler.in '0s', :blocking => true do
|
720
|
+
sleep 2
|
200
721
|
end
|
722
|
+
|
723
|
+
sleep 0.4
|
724
|
+
|
725
|
+
@scheduler.jobs.size.should == 1
|
726
|
+
end
|
727
|
+
|
728
|
+
it 'does not return unscheduled jobs' do
|
729
|
+
|
730
|
+
job =
|
731
|
+
@scheduler.schedule_in '0s', :blocking => true do
|
732
|
+
sleep 2
|
733
|
+
end
|
734
|
+
|
735
|
+
sleep 0.4
|
736
|
+
|
737
|
+
job.unschedule
|
738
|
+
|
739
|
+
@scheduler.jobs.size.should == 0
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
743
|
+
describe '#jobs(:tag / :tags => x)' do
|
744
|
+
|
745
|
+
it 'returns [] when there are no jobs with the corresponding tag' do
|
746
|
+
|
747
|
+
@scheduler.jobs(:tag => 'nada').should == []
|
748
|
+
@scheduler.jobs(:tags => %w[ nada hello ]).should == []
|
749
|
+
end
|
750
|
+
|
751
|
+
it 'returns the jobs with the corresponding tag' do
|
752
|
+
|
753
|
+
@scheduler.in '10d', :tag => 't0' do; end
|
754
|
+
@scheduler.every '2h', :tag => %w[ t0 t1 ] do; end
|
755
|
+
@scheduler.every '3h' do; end
|
756
|
+
|
757
|
+
@scheduler.jobs(:tags => 't0').map(&:original).sort.should ==
|
758
|
+
%w[ 10d 2h ]
|
759
|
+
@scheduler.jobs(:tags => 't1').map(&:original).sort.should ==
|
760
|
+
%w[ 2h ]
|
761
|
+
@scheduler.jobs(:tags => [ 't1', 't0' ]).map(&:original).sort.should ==
|
762
|
+
%w[ 2h ]
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
describe '#every_jobs' do
|
767
|
+
|
768
|
+
it 'returns EveryJob instances' do
|
769
|
+
|
770
|
+
@scheduler.at '2030/12/12 12:10:00' do; end
|
771
|
+
@scheduler.in '10d' do; end
|
772
|
+
@scheduler.every '5m' do; end
|
773
|
+
|
774
|
+
jobs = @scheduler.every_jobs
|
775
|
+
|
776
|
+
jobs.collect { |j| j.original }.sort.should == %w[ 5m ]
|
777
|
+
end
|
778
|
+
end
|
779
|
+
|
780
|
+
describe '#at_jobs' do
|
781
|
+
|
782
|
+
it 'returns AtJob instances' do
|
783
|
+
|
784
|
+
@scheduler.at '2030/12/12 12:10:00' do; end
|
785
|
+
@scheduler.in '10d' do; end
|
786
|
+
@scheduler.every '5m' do; end
|
787
|
+
|
788
|
+
jobs = @scheduler.at_jobs
|
789
|
+
|
790
|
+
jobs.collect { |j| j.original }.sort.should == [ '2030/12/12 12:10:00' ]
|
791
|
+
end
|
792
|
+
end
|
793
|
+
|
794
|
+
describe '#in_jobs' do
|
795
|
+
|
796
|
+
it 'returns InJob instances' do
|
797
|
+
|
798
|
+
@scheduler.at '2030/12/12 12:10:00' do; end
|
799
|
+
@scheduler.in '10d' do; end
|
800
|
+
@scheduler.every '5m' do; end
|
801
|
+
|
802
|
+
jobs = @scheduler.in_jobs
|
803
|
+
|
804
|
+
jobs.collect { |j| j.original }.sort.should == %w[ 10d ]
|
805
|
+
end
|
806
|
+
end
|
807
|
+
|
808
|
+
describe '#cron_jobs' do
|
809
|
+
|
810
|
+
it 'returns CronJob instances' do
|
811
|
+
|
812
|
+
@scheduler.at '2030/12/12 12:10:00' do; end
|
813
|
+
@scheduler.in '10d' do; end
|
814
|
+
@scheduler.every '5m' do; end
|
815
|
+
@scheduler.cron '* * * * *' do; end
|
816
|
+
|
817
|
+
jobs = @scheduler.cron_jobs
|
818
|
+
|
819
|
+
jobs.collect { |j| j.original }.sort.should == [ '* * * * *' ]
|
820
|
+
end
|
821
|
+
end
|
822
|
+
|
823
|
+
describe '#interval_jobs' do
|
824
|
+
|
825
|
+
it 'returns IntervalJob instances' do
|
826
|
+
|
827
|
+
@scheduler.at '2030/12/12 12:10:00' do; end
|
828
|
+
@scheduler.in '10d' do; end
|
829
|
+
@scheduler.every '5m' do; end
|
830
|
+
@scheduler.cron '* * * * *' do; end
|
831
|
+
@scheduler.interval '7m' do; end
|
832
|
+
|
833
|
+
jobs = @scheduler.interval_jobs
|
834
|
+
|
835
|
+
jobs.collect { |j| j.original }.sort.should == %w[ 7m ]
|
201
836
|
end
|
202
837
|
end
|
203
838
|
|
204
|
-
|
839
|
+
#--
|
840
|
+
# callbacks
|
841
|
+
#++
|
205
842
|
|
206
|
-
|
843
|
+
describe '#on_pre_trigger' do
|
207
844
|
|
208
|
-
|
845
|
+
it 'is called right before a job triggers' do
|
209
846
|
|
210
|
-
|
211
|
-
$cron = nil
|
847
|
+
$out = []
|
212
848
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
849
|
+
def @scheduler.on_pre_trigger(job)
|
850
|
+
$out << "pre #{job.id}"
|
851
|
+
end
|
852
|
+
|
853
|
+
job_id =
|
854
|
+
@scheduler.in '0.5s' do |job|
|
855
|
+
$out << job.id
|
218
856
|
end
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
857
|
+
|
858
|
+
sleep 0.7
|
859
|
+
|
860
|
+
$out.should == [ "pre #{job_id}", job_id ]
|
861
|
+
end
|
862
|
+
|
863
|
+
it 'accepts the job and the triggerTime as argument' do
|
864
|
+
|
865
|
+
$tt = nil
|
866
|
+
|
867
|
+
def @scheduler.on_pre_trigger(job, trigger_time)
|
868
|
+
$tt = trigger_time
|
869
|
+
end
|
870
|
+
|
871
|
+
start = Time.now
|
872
|
+
|
873
|
+
@scheduler.in '0.5s' do; end
|
874
|
+
|
875
|
+
sleep 0.7
|
876
|
+
|
877
|
+
$tt.class.should == Time
|
878
|
+
$tt.should > start
|
879
|
+
$tt.should < Time.now
|
880
|
+
end
|
881
|
+
|
882
|
+
context 'when it returns false' do
|
883
|
+
|
884
|
+
it 'prevents the job from triggering' do
|
885
|
+
|
886
|
+
$out = []
|
887
|
+
|
888
|
+
def @scheduler.on_pre_trigger(job)
|
889
|
+
$out << "pre #{job.id}"
|
890
|
+
false
|
223
891
|
end
|
224
892
|
|
225
|
-
|
893
|
+
job_id =
|
894
|
+
@scheduler.in '0.5s' do |job|
|
895
|
+
$out << job.id
|
896
|
+
end
|
226
897
|
|
227
|
-
|
898
|
+
sleep 0.7
|
228
899
|
|
229
|
-
|
230
|
-
$every.should == :out
|
231
|
-
$cron.should == :out
|
900
|
+
$out.should == [ "pre #{job_id}" ]
|
232
901
|
end
|
233
902
|
end
|
234
903
|
end
|
235
|
-
end
|
236
904
|
|
237
|
-
describe '
|
905
|
+
describe '#on_post_trigger' do
|
906
|
+
|
907
|
+
it 'is called right after a job triggers' do
|
908
|
+
|
909
|
+
$out = []
|
238
910
|
|
239
|
-
|
911
|
+
def @scheduler.on_post_trigger(job)
|
912
|
+
$out << "post #{job.id}"
|
913
|
+
end
|
240
914
|
|
241
|
-
|
915
|
+
job_id =
|
916
|
+
@scheduler.in '0.5s' do |job|
|
917
|
+
$out << job.id
|
918
|
+
end
|
242
919
|
|
243
|
-
|
920
|
+
sleep 0.7
|
244
921
|
|
245
|
-
|
922
|
+
$out.should == [ job_id, "post #{job_id}" ]
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
#--
|
927
|
+
# misc
|
928
|
+
#++
|
929
|
+
|
930
|
+
describe '.singleton / .s' do
|
931
|
+
|
932
|
+
before(:each) do
|
933
|
+
|
934
|
+
Rufus::Scheduler.class_eval { @singleton = nil } # ;-)
|
935
|
+
end
|
936
|
+
|
937
|
+
it 'returns a singleton instance of the scheduler' do
|
938
|
+
|
939
|
+
s0 = Rufus::Scheduler.singleton
|
940
|
+
s1 = Rufus::Scheduler.s
|
941
|
+
|
942
|
+
s0.class.should == Rufus::Scheduler
|
943
|
+
s1.object_id.should == s0.object_id
|
944
|
+
end
|
945
|
+
|
946
|
+
it 'accepts initialization parameters' do
|
947
|
+
|
948
|
+
s = Rufus::Scheduler.singleton(:max_work_threads => 77)
|
949
|
+
s = Rufus::Scheduler.singleton(:max_work_threads => 42)
|
950
|
+
|
951
|
+
s.max_work_threads.should == 77
|
952
|
+
end
|
246
953
|
end
|
247
954
|
end
|
248
955
|
|