rufus-scheduler 2.0.24 → 3.1.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 +76 -0
- data/CREDITS.txt +23 -0
- data/LICENSE.txt +1 -1
- data/README.md +1439 -0
- data/Rakefile +1 -5
- data/TODO.txt +149 -55
- data/lib/rufus/{sc → scheduler}/cronline.rb +167 -53
- data/lib/rufus/scheduler/job_array.rb +92 -0
- data/lib/rufus/scheduler/jobs.rb +633 -0
- data/lib/rufus/scheduler/locks.rb +95 -0
- data/lib/rufus/scheduler/util.rb +306 -0
- data/lib/rufus/scheduler/zones.rb +174 -0
- data/lib/rufus/scheduler/zotime.rb +154 -0
- data/lib/rufus/scheduler.rb +608 -27
- data/rufus-scheduler.gemspec +6 -4
- data/spec/basics_spec.rb +54 -0
- data/spec/cronline_spec.rb +479 -152
- data/spec/error_spec.rb +139 -0
- data/spec/job_array_spec.rb +39 -0
- data/spec/job_at_spec.rb +58 -0
- data/spec/job_cron_spec.rb +128 -0
- data/spec/job_every_spec.rb +104 -0
- data/spec/job_in_spec.rb +20 -0
- data/spec/job_interval_spec.rb +68 -0
- data/spec/job_repeat_spec.rb +357 -0
- data/spec/job_spec.rb +498 -109
- data/spec/lock_custom_spec.rb +47 -0
- data/spec/lock_flock_spec.rb +47 -0
- data/spec/lock_lockfile_spec.rb +61 -0
- data/spec/lock_spec.rb +59 -0
- data/spec/parse_spec.rb +263 -0
- data/spec/schedule_at_spec.rb +158 -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 +928 -124
- data/spec/spec_helper.rb +126 -0
- data/spec/threads_spec.rb +96 -0
- data/spec/zotime_spec.rb +396 -0
- metadata +56 -33
- 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/lib/rufus/sc/version.rb +0 -32
- 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,357 @@
|
|
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::RepeatJob 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 '#pause' do
|
21
|
+
|
22
|
+
it 'pauses the job' do
|
23
|
+
|
24
|
+
counter = 0
|
25
|
+
|
26
|
+
job =
|
27
|
+
@scheduler.schedule_every('0.5s') do
|
28
|
+
counter += 1
|
29
|
+
end
|
30
|
+
|
31
|
+
expect(counter).to eq(0)
|
32
|
+
|
33
|
+
while counter < 1; sleep(0.1); end
|
34
|
+
|
35
|
+
job.pause
|
36
|
+
|
37
|
+
sleep(1)
|
38
|
+
|
39
|
+
expect(counter).to eq(1)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#paused?' do
|
44
|
+
|
45
|
+
it 'returns true if the job is paused' do
|
46
|
+
|
47
|
+
job = @scheduler.schedule_every('10s') do; end
|
48
|
+
|
49
|
+
job.pause
|
50
|
+
|
51
|
+
expect(job.paused?).to eq(true)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns false if the job is not paused' do
|
55
|
+
|
56
|
+
job = @scheduler.schedule_every('10s') do; end
|
57
|
+
|
58
|
+
expect(job.paused?).to eq(false)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '#resume' do
|
63
|
+
|
64
|
+
it 'resumes a paused job' do
|
65
|
+
|
66
|
+
counter = 0
|
67
|
+
|
68
|
+
job =
|
69
|
+
@scheduler.schedule_every('0.5s') do
|
70
|
+
counter += 1
|
71
|
+
end
|
72
|
+
|
73
|
+
job.pause
|
74
|
+
job.resume
|
75
|
+
|
76
|
+
sleep(1.5)
|
77
|
+
|
78
|
+
expect(counter).to be > 1
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'has no effect on a not paused job' do
|
82
|
+
|
83
|
+
job = @scheduler.schedule_every('10s') do; end
|
84
|
+
|
85
|
+
job.resume
|
86
|
+
|
87
|
+
expect(job.paused?).to eq(false)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe ':times => i' do
|
92
|
+
|
93
|
+
it 'lets a job unschedule itself after i times' do
|
94
|
+
|
95
|
+
counter = 0
|
96
|
+
|
97
|
+
job =
|
98
|
+
@scheduler.schedule_every '0.5s', :times => 3 do
|
99
|
+
counter = counter + 1
|
100
|
+
end
|
101
|
+
|
102
|
+
sleep(2.6)
|
103
|
+
|
104
|
+
expect(counter).to eq(3)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'is OK when passed a nil instead of an integer' do
|
108
|
+
|
109
|
+
counter = 0
|
110
|
+
|
111
|
+
job =
|
112
|
+
@scheduler.schedule_every '0.5s', :times => nil do
|
113
|
+
counter = counter + 1
|
114
|
+
end
|
115
|
+
|
116
|
+
sleep(2.5)
|
117
|
+
|
118
|
+
expect(counter).to be > 3
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'raises when passed something else than nil or an integer' do
|
122
|
+
|
123
|
+
expect {
|
124
|
+
@scheduler.schedule_every '0.5s', :times => 'nada' do; end
|
125
|
+
}.to raise_error(ArgumentError)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe ':first/:first_in/:first_at => point in time' do
|
130
|
+
|
131
|
+
it 'accepts a Time instance' do
|
132
|
+
|
133
|
+
t = Time.now + 10
|
134
|
+
|
135
|
+
job = @scheduler.schedule_every '0.5s', :first => t do; end
|
136
|
+
|
137
|
+
expect(job.first_at).to eq(t)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'accepts a time string' do
|
141
|
+
|
142
|
+
t = Time.now + 10
|
143
|
+
|
144
|
+
job = @scheduler.schedule_every '0.5s', :first => t.to_s do; end
|
145
|
+
|
146
|
+
expect(job.first_at.to_s).to eq(t.to_s)
|
147
|
+
expect(job.first_at.zone).to eq(t.zone)
|
148
|
+
end
|
149
|
+
|
150
|
+
it 'only lets the job trigger after the :first' do
|
151
|
+
|
152
|
+
t = Time.now + 1.4
|
153
|
+
counter = 0
|
154
|
+
|
155
|
+
job =
|
156
|
+
@scheduler.schedule_every '0.5s', :first => t do
|
157
|
+
counter = counter + 1
|
158
|
+
end
|
159
|
+
|
160
|
+
sleep(1)
|
161
|
+
|
162
|
+
expect(counter).to eq(0)
|
163
|
+
|
164
|
+
sleep(1)
|
165
|
+
|
166
|
+
expect(counter).to be > 0
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'raises on points in the past' do
|
170
|
+
|
171
|
+
expect {
|
172
|
+
|
173
|
+
@scheduler.schedule_every '0.5s', :first => Time.now - 60 do; end
|
174
|
+
|
175
|
+
}.to raise_error(ArgumentError)
|
176
|
+
end
|
177
|
+
|
178
|
+
context ':first_time => :now/:immediately' do
|
179
|
+
|
180
|
+
it 'schedules the first execution immediately' do
|
181
|
+
|
182
|
+
n = Time.now
|
183
|
+
ft = nil
|
184
|
+
|
185
|
+
job =
|
186
|
+
@scheduler.schedule_every '7s', :first => :now do
|
187
|
+
ft ||= Time.now
|
188
|
+
end
|
189
|
+
|
190
|
+
sleep 0.7
|
191
|
+
|
192
|
+
#p Time.now.to_f
|
193
|
+
#p n.to_f
|
194
|
+
#p job.first_at.to_f
|
195
|
+
#p ft.to_f
|
196
|
+
|
197
|
+
expect(job.first_at).to be < n + 0.7
|
198
|
+
expect(ft).to be < job.first_at + @scheduler.frequency + 0.1
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
describe ':first/:first_in/:first_at => duration' do
|
204
|
+
|
205
|
+
it 'accepts a duration string' do
|
206
|
+
|
207
|
+
t = Time.now
|
208
|
+
|
209
|
+
job = @scheduler.schedule_every '0.5s', :first => '1h' do; end
|
210
|
+
|
211
|
+
expect(job.first_at).to be >= t + 3600
|
212
|
+
expect(job.first_at).to be < t + 3601
|
213
|
+
end
|
214
|
+
|
215
|
+
it 'accepts a duration in seconds (integer)' do
|
216
|
+
|
217
|
+
t = Time.now
|
218
|
+
|
219
|
+
job = @scheduler.schedule_every '0.5s', :first => 3600 do; end
|
220
|
+
|
221
|
+
expect(job.first_at).to be >= t + 3600
|
222
|
+
expect(job.first_at).to be < t + 3601
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'raises if the argument cannot be used' do
|
226
|
+
|
227
|
+
expect {
|
228
|
+
@scheduler.every '0.5s', :first => :nada do; end
|
229
|
+
}.to raise_error(ArgumentError)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe '#first_at=' do
|
234
|
+
|
235
|
+
it 'can be used to set first_at directly' do
|
236
|
+
|
237
|
+
job = @scheduler.schedule_every '0.5s', :first => 3600 do; end
|
238
|
+
job.first_at = '2030-12-12 12:00:30'
|
239
|
+
|
240
|
+
expect(job.first_at.strftime('%c')).to eq('Thu Dec 12 12:00:30 2030')
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
describe ':last/:last_in/:last_at => point in time' do
|
245
|
+
|
246
|
+
it 'accepts a Time instance' do
|
247
|
+
|
248
|
+
t = Time.now + 10
|
249
|
+
|
250
|
+
job = @scheduler.schedule_every '0.5s', :last => t do; end
|
251
|
+
|
252
|
+
expect(job.last_at).to eq(t)
|
253
|
+
end
|
254
|
+
|
255
|
+
it 'unschedules the job after the last_at time' do
|
256
|
+
|
257
|
+
t = Time.now + 2
|
258
|
+
|
259
|
+
counter = 0
|
260
|
+
tt = nil
|
261
|
+
|
262
|
+
job =
|
263
|
+
@scheduler.schedule_every '0.5s', :last => t do
|
264
|
+
counter = counter + 1
|
265
|
+
tt = Time.now
|
266
|
+
end
|
267
|
+
|
268
|
+
sleep 3
|
269
|
+
|
270
|
+
#counter.should == 3
|
271
|
+
expect([ 3, 4 ]).to include(counter)
|
272
|
+
expect(tt).to be < t
|
273
|
+
expect(@scheduler.jobs).not_to include(job)
|
274
|
+
end
|
275
|
+
|
276
|
+
it 'accepts a time string' do
|
277
|
+
|
278
|
+
t = Time.now + 10
|
279
|
+
|
280
|
+
job = @scheduler.schedule_every '0.5s', :last => t.to_s do; end
|
281
|
+
|
282
|
+
expect(job.last_at.to_s).to eq(t.to_s)
|
283
|
+
expect(job.last_at.zone).to eq(t.zone)
|
284
|
+
end
|
285
|
+
|
286
|
+
it 'raises on a point in the past' do
|
287
|
+
|
288
|
+
expect {
|
289
|
+
|
290
|
+
@scheduler.every '0.5s', :last => Time.now - 60 do; end
|
291
|
+
|
292
|
+
}.to raise_error(ArgumentError)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe ':last/:last_in/:last_at => duration' do
|
297
|
+
|
298
|
+
it 'accepts a duration string' do
|
299
|
+
|
300
|
+
t = Time.now
|
301
|
+
|
302
|
+
job = @scheduler.schedule_every '0.5s', :last_in => '2s' do; end
|
303
|
+
|
304
|
+
expect(job.last_at).to be >= t + 2
|
305
|
+
expect(job.last_at).to be < t + 2.5
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'accepts a duration in seconds (integer)' do
|
309
|
+
|
310
|
+
t = Time.now
|
311
|
+
|
312
|
+
job = @scheduler.schedule_every '0.5s', :last_in => 2.0 do; end
|
313
|
+
|
314
|
+
expect(job.last_at).to be >= t + 2
|
315
|
+
expect(job.last_at).to be < t + 2.5
|
316
|
+
end
|
317
|
+
|
318
|
+
it 'raises if the argument is worthless' do
|
319
|
+
|
320
|
+
expect {
|
321
|
+
@scheduler.every '0.5s', :last => :nada do; end
|
322
|
+
}.to raise_error(ArgumentError)
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
describe '#last_at=' do
|
327
|
+
|
328
|
+
it 'can be used to set last_at directly' do
|
329
|
+
|
330
|
+
job = @scheduler.schedule_every '0.5s', :last_in => 10.0 do; end
|
331
|
+
job.last_at = '2030-12-12 12:00:30'
|
332
|
+
|
333
|
+
expect(job.last_at.strftime('%c')).to eq('Thu Dec 12 12:00:30 2030')
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe '#count' do
|
338
|
+
|
339
|
+
it 'starts at 0' do
|
340
|
+
|
341
|
+
job = @scheduler.schedule_every '5m' do; end
|
342
|
+
|
343
|
+
expect(job.count).to eq(0)
|
344
|
+
end
|
345
|
+
|
346
|
+
it 'keeps track of how many times the job fired' do
|
347
|
+
|
348
|
+
job = @scheduler.schedule_every '0.5s' do; end
|
349
|
+
|
350
|
+
sleep(2.0)
|
351
|
+
|
352
|
+
expect(job.count).to be >= 3
|
353
|
+
expect(job.count).to be <= 4
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|