rufus-scheduler 2.0.17 → 2.0.18
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +7 -0
- data/CREDITS.txt +4 -0
- data/LICENSE.txt +1 -1
- data/README.rdoc +13 -11
- data/lib/rufus/sc/cronline.rb +54 -34
- data/lib/rufus/sc/jobqueues.rb +1 -1
- data/lib/rufus/sc/jobs.rb +2 -2
- data/lib/rufus/sc/rtime.rb +31 -24
- data/lib/rufus/sc/scheduler.rb +1 -1
- data/lib/rufus/sc/version.rb +2 -2
- data/lib/rufus/scheduler.rb +1 -1
- data/spec/blocking_spec.rb +16 -12
- data/spec/cronline_spec.rb +53 -1
- data/spec/rtime_spec.rb +24 -0
- metadata +52 -32
- data/out.txt +0 -4
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
= rufus-scheduler CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-scheduler - 2.0.18 released 2012/03/06
|
6
|
+
|
7
|
+
- support for "L" in cron lines (Thanks Andrew Davey)
|
8
|
+
- support for negative time strings (Thanks Danny "northox" Fullerton)
|
9
|
+
- reject invalid weekdays (Thanks pazustep)
|
10
|
+
|
11
|
+
|
5
12
|
== rufus-scheduler - 2.0.17 released 2012/06/14
|
6
13
|
|
7
14
|
- @andrehjr patch to make it work on Ruby 1.9.3
|
data/CREDITS.txt
CHANGED
@@ -4,6 +4,10 @@
|
|
4
4
|
|
5
5
|
== Contributors
|
6
6
|
|
7
|
+
- Andrew Davey (https://github.com/asdavey) "L" in cron lines
|
8
|
+
- Stig Kleppe-Jørgensen (https://github.com/stigkj)
|
9
|
+
- Danny "northox" Fullerton (https://github.com/northox) negative time strings
|
10
|
+
- Marcus Brito (https://github.com/pazustep) CronLine proofing
|
7
11
|
- André Luis Leal Cardoso Junior (https://github.com/andrehjr) 1.9.3 patch
|
8
12
|
- Anthony Lewis (https://github.com/anthonylewis) cron lines and 09 issue
|
9
13
|
- concept47 (https://github.com/concept47) every and :discard_past
|
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Copyright (c) 2005-
|
2
|
+
Copyright (c) 2005-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.rdoc
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
= rufus-scheduler
|
3
2
|
|
4
3
|
rufus-scheduler is a Ruby gem for scheduling pieces of code (jobs). It understands running a job AT a certain time, IN a certain time, EVERY x time or simply via a CRON statement.
|
@@ -60,10 +59,10 @@ This PlainScheduler accepts a :thread_name option :
|
|
60
59
|
|
61
60
|
scheduler = Rufus::Scheduler::PlainScheduler.start_new(:thread_name => 'my scheduler')
|
62
61
|
|
63
|
-
might be helpful when tracking threads.
|
62
|
+
which might be helpful when tracking threads.
|
64
63
|
|
65
64
|
|
66
|
-
Note that
|
65
|
+
Note that if there is an EventMachine present and running,
|
67
66
|
|
68
67
|
scheduler = Rufus::Scheduler.start_new
|
69
68
|
|
@@ -78,12 +77,16 @@ This is a classical cron :
|
|
78
77
|
# every day of the week at 22:00 (10pm)
|
79
78
|
end
|
80
79
|
|
81
|
-
Rufus-scheduler supports
|
80
|
+
Rufus-scheduler supports three variants to that notation : seconds, last day of month and timezones.
|
82
81
|
|
83
82
|
scheduler.cron '13 0 22 * * 1-5' do
|
84
83
|
# every day of the week at 22:00:13
|
85
84
|
end
|
86
85
|
|
86
|
+
scheduler.cron '0 22 L * *' do
|
87
|
+
# every month on the last day at 22:00
|
88
|
+
end
|
89
|
+
|
87
90
|
scheduler.cron '0 22 * * 1-5 Europe/Paris' do
|
88
91
|
# every day of the week when it's 22:00 in Paris
|
89
92
|
end
|
@@ -120,7 +123,7 @@ If you place
|
|
120
123
|
|
121
124
|
scheduler.join
|
122
125
|
|
123
|
-
at
|
126
|
+
at the end, it will make the current (main) thread join the scheduler and prevent the Ruby runtime from exiting.
|
124
127
|
|
125
128
|
You shouldn't be exposed to this issue when using EventMachine, since while running EM, your runtime won't exit.
|
126
129
|
|
@@ -200,7 +203,7 @@ If at 4pm the scheduler is in a blocking task, there will be no four o'clock tea
|
|
200
203
|
puts "order espresso"
|
201
204
|
end
|
202
205
|
|
203
|
-
the "order espresso" will only get triggered once the ristretto has been consumed. Rufus-scheduler
|
206
|
+
the "order espresso" will only get triggered once the ristretto has been consumed. Rufus-scheduler will create a 'that_mutex' mutex and keep track of it. Don't go on passing too many different mutex names, rufus-scheduler will keep track of each of them (they won't get garbage collected).
|
204
207
|
|
205
208
|
It's OK to use a mutex directly:
|
206
209
|
|
@@ -240,7 +243,7 @@ By default, every and cron jobs will "overlap":
|
|
240
243
|
end
|
241
244
|
end
|
242
245
|
|
243
|
-
You
|
246
|
+
You might end up with something that looks like
|
244
247
|
|
245
248
|
hello 0
|
246
249
|
hello 1
|
@@ -250,7 +253,7 @@ You mind end up with something that looks like
|
|
250
253
|
hello 4
|
251
254
|
...
|
252
255
|
|
253
|
-
This every job
|
256
|
+
This every job will have overlaps. To prevent that:
|
254
257
|
|
255
258
|
scheduler.every '3s', :allow_overlapping => false do
|
256
259
|
# ...
|
@@ -446,7 +449,7 @@ This timeout feature relies on an 'in' job scheduled at the moment the main job
|
|
446
449
|
|
447
450
|
== exceptions in jobs
|
448
451
|
|
449
|
-
By default, when
|
452
|
+
By default, when exceptions occur when a job performs, the error messages will be output to the STDOUT.
|
450
453
|
|
451
454
|
It's easy to customize that behaviour :
|
452
455
|
|
@@ -564,7 +567,7 @@ http://github.com/jmettraux/rufus-scheduler/blob/master/CREDITS.txt
|
|
564
567
|
|
565
568
|
== authors
|
566
569
|
|
567
|
-
John Mettraux, jmettraux@gmail.com, http://jmettraux.
|
570
|
+
John Mettraux, jmettraux@gmail.com, http://jmettraux.github.com
|
568
571
|
|
569
572
|
|
570
573
|
== the rest of Rufus
|
@@ -575,4 +578,3 @@ http://rufus.rubyforge.org
|
|
575
578
|
== license
|
576
579
|
|
577
580
|
MIT
|
578
|
-
|
data/lib/rufus/sc/cronline.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -69,6 +69,13 @@ module Rufus
|
|
69
69
|
@days = parse_item(items[2 + offset], 1, 31)
|
70
70
|
@months = parse_item(items[3 + offset], 1, 12)
|
71
71
|
@weekdays, @monthdays = parse_weekdays(items[4 + offset])
|
72
|
+
|
73
|
+
[ @seconds, @minutes, @hours, @months ].each do |es|
|
74
|
+
|
75
|
+
raise ArgumentError.new(
|
76
|
+
"invalid cronline: '#{line}'"
|
77
|
+
) if es && es.find { |e| ! e.is_a?(Integer) }
|
78
|
+
end
|
72
79
|
end
|
73
80
|
|
74
81
|
# Returns true if the given time matches this cron line.
|
@@ -79,9 +86,9 @@ module Rufus
|
|
79
86
|
|
80
87
|
time = @timezone.utc_to_local(time.getutc) if @timezone
|
81
88
|
|
82
|
-
return false unless sub_match?(time
|
83
|
-
return false unless sub_match?(time
|
84
|
-
return false unless sub_match?(time
|
89
|
+
return false unless sub_match?(time, :sec, @seconds)
|
90
|
+
return false unless sub_match?(time, :min, @minutes)
|
91
|
+
return false unless sub_match?(time, :hour, @hours)
|
85
92
|
return false unless date_match?(time)
|
86
93
|
true
|
87
94
|
end
|
@@ -126,15 +133,15 @@ module Rufus
|
|
126
133
|
time += (24 - time.hour) * 3600 - time.min * 60 - time.sec
|
127
134
|
next
|
128
135
|
end
|
129
|
-
unless sub_match?(time
|
136
|
+
unless sub_match?(time, :hour, @hours)
|
130
137
|
time += (60 - time.min) * 60 - time.sec
|
131
138
|
next
|
132
139
|
end
|
133
|
-
unless sub_match?(time
|
140
|
+
unless sub_match?(time, :min, @minutes)
|
134
141
|
time += 60 - time.sec
|
135
142
|
next
|
136
143
|
end
|
137
|
-
unless sub_match?(time
|
144
|
+
unless sub_match?(time, :sec, @seconds)
|
138
145
|
time += 1
|
139
146
|
next
|
140
147
|
end
|
@@ -192,10 +199,14 @@ module Rufus
|
|
192
199
|
(monthdays ||= []) << it
|
193
200
|
|
194
201
|
else
|
202
|
+
expr = it.dup
|
203
|
+
WEEKDAYS.each_with_index { |a, i| expr.gsub!(/#{a}/, i.to_s) }
|
195
204
|
|
196
|
-
|
205
|
+
raise ArgumentError.new(
|
206
|
+
"invalid weekday expression (#{it})"
|
207
|
+
) if expr !~ /^0*[0-7](-0*[0-7])?$/
|
197
208
|
|
198
|
-
its =
|
209
|
+
its = expr.index('-') ? parse_range(expr, 0, 7) : [ Integer(expr) ]
|
199
210
|
its = its.collect { |i| i == 7 ? 0 : i }
|
200
211
|
|
201
212
|
(weekdays ||= []).concat(its)
|
@@ -210,8 +221,9 @@ module Rufus
|
|
210
221
|
def parse_item(item, min, max)
|
211
222
|
|
212
223
|
return nil if item == '*'
|
224
|
+
return [ 'L' ] if item == 'L'
|
213
225
|
return parse_list(item, min, max) if item.index(',')
|
214
|
-
return parse_range(item, min, max) if item.
|
226
|
+
return parse_range(item, min, max) if item.match(/[*-\/]/)
|
215
227
|
|
216
228
|
i = item.to_i
|
217
229
|
|
@@ -223,32 +235,36 @@ module Rufus
|
|
223
235
|
|
224
236
|
def parse_list(item, min, max)
|
225
237
|
|
226
|
-
item.split(',').
|
227
|
-
|
228
|
-
|
238
|
+
l = item.split(',').collect { |i| parse_range(i, min, max) }.flatten
|
239
|
+
|
240
|
+
raise ArgumentError.new(
|
241
|
+
"found duplicates in #{item.inspect}"
|
242
|
+
) if l.uniq.size < l.size
|
243
|
+
|
244
|
+
l
|
229
245
|
end
|
230
246
|
|
231
247
|
def parse_range(item, min, max)
|
232
248
|
|
233
|
-
|
234
|
-
|
249
|
+
dash = item.index('-')
|
250
|
+
slash = item.index('/')
|
235
251
|
|
236
|
-
return item
|
252
|
+
return parse_item(item, min, max) if (not slash) and (not dash)
|
237
253
|
|
238
|
-
|
254
|
+
raise ArgumentError.new(
|
255
|
+
"'L' (end of month) is not accepted in ranges, " +
|
256
|
+
"#{item.inspect} is not valid"
|
257
|
+
) if item.index('L')
|
258
|
+
|
259
|
+
inc = slash ? item[slash + 1..-1].to_i : 1
|
239
260
|
|
240
261
|
istart = -1
|
241
262
|
iend = -1
|
242
263
|
|
243
|
-
if
|
244
|
-
|
245
|
-
istart = item[0..i - 1].to_i
|
264
|
+
if dash
|
246
265
|
|
247
|
-
|
248
|
-
|
249
|
-
else
|
250
|
-
item[i + 1..-1].to_i
|
251
|
-
end
|
266
|
+
istart = item[0..dash - 1].to_i
|
267
|
+
iend = (slash ? item[dash + 1..slash - 1] : item[dash + 1..-1]).to_i
|
252
268
|
|
253
269
|
else # case */x
|
254
270
|
|
@@ -271,22 +287,26 @@ module Rufus
|
|
271
287
|
result
|
272
288
|
end
|
273
289
|
|
274
|
-
def sub_match?(
|
290
|
+
def sub_match?(time, accessor, values=:none)
|
275
291
|
|
276
|
-
values
|
277
|
-
|
292
|
+
value, values =
|
293
|
+
if values == :none
|
294
|
+
[ time, accessor ]
|
295
|
+
else
|
296
|
+
[ time.send(accessor), values ]
|
297
|
+
end
|
278
298
|
|
279
|
-
|
299
|
+
return true if values.nil?
|
300
|
+
return true if values.include?('L') && (time + 24 * 3600).day == 1
|
280
301
|
|
281
|
-
|
282
|
-
return true if monthdays.include?(monthday)
|
302
|
+
values.include?(value)
|
283
303
|
end
|
284
304
|
|
285
305
|
def date_match?(date)
|
286
306
|
|
287
|
-
return false unless sub_match?(date
|
288
|
-
return false unless sub_match?(date
|
289
|
-
return false unless sub_match?(date
|
307
|
+
return false unless sub_match?(date, :day, @days)
|
308
|
+
return false unless sub_match?(date, :month, @months)
|
309
|
+
return false unless sub_match?(date, :wday, @weekdays)
|
290
310
|
return false unless sub_match?(CronLine.monthday(date), @monthdays)
|
291
311
|
true
|
292
312
|
end
|
data/lib/rufus/sc/jobqueues.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
data/lib/rufus/sc/jobs.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -30,7 +30,7 @@ module Scheduler
|
|
30
30
|
# The base class for all types of jobs.
|
31
31
|
#
|
32
32
|
class Job
|
33
|
-
|
33
|
+
|
34
34
|
# A reference to the scheduler owning this job
|
35
35
|
#
|
36
36
|
attr_accessor :scheduler
|
data/lib/rufus/sc/rtime.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2005-
|
2
|
+
# Copyright (c) 2005-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -96,8 +96,6 @@ module Rufus
|
|
96
96
|
(Time.new.to_f * 1000).to_i
|
97
97
|
end
|
98
98
|
|
99
|
-
FLOAT_DURATION = /^\d*\.\d*$/
|
100
|
-
|
101
99
|
# Turns a string like '1m10s' into a float like '70.0', more formally,
|
102
100
|
# turns a time duration expressed as a string into a Float instance
|
103
101
|
# (millisecond count).
|
@@ -120,24 +118,35 @@ module Rufus
|
|
120
118
|
# Rufus.parse_time_string "1h10s" # => 3610.0
|
121
119
|
# Rufus.parse_time_string "1w2d" # => 777600.0
|
122
120
|
#
|
123
|
-
def
|
124
|
-
|
125
|
-
if m = string.match(/^(\d*)\.?(\d*)([A-Za-z])(.*)$/)
|
121
|
+
def self.parse_time_string(string)
|
126
122
|
|
127
|
-
|
128
|
-
multiplier = DURATIONS[m[3]]
|
123
|
+
return 0.0 if string == ''
|
129
124
|
|
130
|
-
|
125
|
+
m = string.match(/^(-?)([\d\.#{DURATION_LETTERS}]+)$/)
|
131
126
|
|
132
|
-
|
127
|
+
raise ArgumentError.new("cannot parse '#{string}'") unless m
|
133
128
|
|
134
|
-
|
129
|
+
mod = m[1] == '-' ? -1.0 : 1.0
|
130
|
+
val = 0.0
|
135
131
|
|
136
|
-
|
137
|
-
return string.to_f if string.match(/^\d*\.?\d*$/)
|
132
|
+
s = m[2]
|
138
133
|
|
139
|
-
|
134
|
+
while s.length > 0
|
135
|
+
m = nil
|
136
|
+
if m = s.match(/^(\d+|\d+\.\d*|\d*\.\d+)([#{DURATION_LETTERS}])(.*)$/)
|
137
|
+
val += m[1].to_f * DURATIONS[m[2]]
|
138
|
+
elsif s.match(/^\d+$/)
|
139
|
+
val += s.to_i / 1000.0
|
140
|
+
elsif s.match(/^\d*\.\d*$/)
|
141
|
+
val += s.to_f
|
142
|
+
else
|
143
|
+
raise ArgumentError.new("cannot parse '#{string}' (especially '#{s}')")
|
144
|
+
end
|
145
|
+
break unless m && m[3]
|
146
|
+
s = m[3]
|
140
147
|
end
|
148
|
+
|
149
|
+
mod * val
|
141
150
|
end
|
142
151
|
|
143
152
|
class << self
|
@@ -185,7 +194,7 @@ module Rufus
|
|
185
194
|
|
186
195
|
def Rufus.to_local_time(dtime)
|
187
196
|
|
188
|
-
to_ttime(dtime.new_offset(DateTime.now.offset-offset), :local)
|
197
|
+
to_ttime(dtime.new_offset(DateTime.now.offset - offset), :local)
|
189
198
|
end
|
190
199
|
|
191
200
|
def Rufus.to_ttime(d, method)
|
@@ -232,7 +241,7 @@ module Rufus
|
|
232
241
|
|
233
242
|
return (options[:drop_seconds] ? '0m' : '0s') if seconds <= 0
|
234
243
|
|
235
|
-
h = to_duration_hash
|
244
|
+
h = to_duration_hash(seconds, options)
|
236
245
|
|
237
246
|
s = DU_KEYS.inject('') { |r, key|
|
238
247
|
count = h[key]
|
@@ -280,7 +289,7 @@ module Rufus
|
|
280
289
|
end
|
281
290
|
|
282
291
|
if options[:drop_seconds]
|
283
|
-
h.delete
|
292
|
+
h.delete(:ms)
|
284
293
|
seconds = (seconds - seconds % 60)
|
285
294
|
end
|
286
295
|
|
@@ -317,8 +326,8 @@ module Rufus
|
|
317
326
|
|
318
327
|
# TODO : use chronic if present
|
319
328
|
|
320
|
-
at =
|
321
|
-
at =
|
329
|
+
at = to_ruby_time(at) if at.is_a?(String)
|
330
|
+
at = to_gm_time(at) if at.is_a?(DateTime)
|
322
331
|
#at = at.to_f if at.is_a?(Time)
|
323
332
|
at = at.to_f if at.respond_to?(:to_f)
|
324
333
|
|
@@ -329,7 +338,7 @@ module Rufus
|
|
329
338
|
at
|
330
339
|
end
|
331
340
|
|
332
|
-
protected
|
341
|
+
protected # well, somehow
|
333
342
|
|
334
343
|
DURATIONS2M = [
|
335
344
|
[ 'y', 365 * 24 * 3600 ],
|
@@ -343,10 +352,8 @@ module Rufus
|
|
343
352
|
DURATIONS2 = DURATIONS2M.dup
|
344
353
|
DURATIONS2.delete_at(1)
|
345
354
|
|
346
|
-
DURATIONS = DURATIONS2M.inject({})
|
347
|
-
|
348
|
-
r
|
349
|
-
end
|
355
|
+
DURATIONS = DURATIONS2M.inject({}) { |r, (k, v)| r[k] = v; r }
|
356
|
+
DURATION_LETTERS = DURATIONS.keys.join
|
350
357
|
|
351
358
|
DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
|
352
359
|
end
|
data/lib/rufus/sc/scheduler.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
data/lib/rufus/sc/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -26,7 +26,7 @@
|
|
26
26
|
module Rufus
|
27
27
|
module Scheduler
|
28
28
|
|
29
|
-
VERSION = '2.0.
|
29
|
+
VERSION = '2.0.18'
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
data/lib/rufus/scheduler.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2013, John Mettraux, jmettraux@gmail.com
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
5
5
|
# of this software and associated documentation files (the "Software"), to deal
|
data/spec/blocking_spec.rb
CHANGED
@@ -17,17 +17,18 @@ describe SCHEDULER_CLASS do
|
|
17
17
|
stop_scheduler(@s)
|
18
18
|
end
|
19
19
|
|
20
|
-
JOB =
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
20
|
+
JOB =
|
21
|
+
Proc.new do |x|
|
22
|
+
begin
|
23
|
+
$var << "a#{x}"
|
24
|
+
sleep 0.500
|
25
|
+
$var << "b#{x}"
|
26
|
+
rescue Exception => e
|
27
|
+
puts '=' * 80
|
28
|
+
p e
|
29
|
+
puts '=' * 80
|
30
|
+
end
|
29
31
|
end
|
30
|
-
end
|
31
32
|
|
32
33
|
context ':blocking => nil' do
|
33
34
|
|
@@ -37,9 +38,12 @@ describe SCHEDULER_CLASS do
|
|
37
38
|
@s.in('1s') { JOB.call(1) }
|
38
39
|
@s.in('1s') { JOB.call(2) }
|
39
40
|
|
40
|
-
sleep
|
41
|
+
sleep 4.0
|
41
42
|
|
42
|
-
[
|
43
|
+
[
|
44
|
+
%w{ a1 a2 b1 b2 }, %w{ a1 a2 b2 b1 },
|
45
|
+
%w{ a2 a1 b2 b1 }, %w{ a2 a1 b1 b2 }
|
46
|
+
].should include($var)
|
43
47
|
end
|
44
48
|
end
|
45
49
|
|
data/spec/cronline_spec.rb
CHANGED
@@ -36,7 +36,7 @@ describe Rufus::CronLine do
|
|
36
36
|
it 'interprets cron strings correctly' do
|
37
37
|
|
38
38
|
to_a '* * * * *', [ [0], nil, nil, nil, nil, nil, nil, nil ]
|
39
|
-
to_a '10-12 * * * *', [ [0], [10, 11, 12], nil, nil,
|
39
|
+
to_a '10-12 * * * *', [ [0], [10, 11, 12], nil, nil, nil, nil, nil, nil ]
|
40
40
|
to_a '* * * * sun,mon', [ [0], nil, nil, nil, nil, [0, 1], nil, nil ]
|
41
41
|
to_a '* * * * mon-wed', [ [0], nil, nil, nil, nil, [1, 2, 3], nil, nil ]
|
42
42
|
to_a '* * * * 7', [ [0], nil, nil, nil, nil, [0], nil, nil ]
|
@@ -56,6 +56,21 @@ describe Rufus::CronLine do
|
|
56
56
|
to_a '0 0 1 1 *', [ [0], [0], [0], [1], [1], nil, nil, nil ]
|
57
57
|
end
|
58
58
|
|
59
|
+
it 'rejects invalid weekday expressions' do
|
60
|
+
|
61
|
+
lambda { cl '0 17 * * MON_FRI' }.should raise_error
|
62
|
+
# underline instead of dash
|
63
|
+
|
64
|
+
lambda { cl '* * * * 9' }.should raise_error
|
65
|
+
lambda { cl '* * * * 0-12' }.should raise_error
|
66
|
+
lambda { cl '* * * * BLABLA' }.should raise_error
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'rejects invalid cronlines' do
|
70
|
+
|
71
|
+
lambda { cl '* nada * * 9' }.should raise_error(ArgumentError)
|
72
|
+
end
|
73
|
+
|
59
74
|
it 'interprets cron strings with TZ correctly' do
|
60
75
|
|
61
76
|
to_a '* * * * * EST', [ [0], nil, nil, nil, nil, nil, nil, 'EST' ]
|
@@ -94,6 +109,29 @@ describe Rufus::CronLine do
|
|
94
109
|
to_a '* 01-09/04 * * *', [ [0], nil, [1, 5, 9], nil, nil, nil, nil, nil ]
|
95
110
|
to_a '* * * * 06', [ [0], nil, nil, nil, nil, [6], nil, nil ]
|
96
111
|
end
|
112
|
+
|
113
|
+
it 'interprets cron strings with L correctly' do
|
114
|
+
|
115
|
+
to_a '* * L * *', [[0], nil, nil, ['L'], nil, nil, nil, nil ]
|
116
|
+
to_a '* * 2-5,L * *', [[0], nil, nil, [2,3,4,5,'L'], nil, nil, nil, nil ]
|
117
|
+
to_a '* * */8,L * *', [[0], nil, nil, [1,9,17,25,'L'], nil, nil, nil, nil ]
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'does not support ranges for L' do
|
121
|
+
|
122
|
+
lambda { cl '* * 15-L * *'}.should raise_error(ArgumentError)
|
123
|
+
lambda { cl '* * L/4 * *'}.should raise_error(ArgumentError)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'does not support multiple Ls' do
|
127
|
+
|
128
|
+
lambda { cl '* * L,L * *'}.should raise_error(ArgumentError)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'raises if L is used for something else than days' do
|
132
|
+
|
133
|
+
lambda { cl '* L * * *'}.should raise_error(ArgumentError)
|
134
|
+
end
|
97
135
|
end
|
98
136
|
|
99
137
|
describe '#next_time' do
|
@@ -207,6 +245,14 @@ describe Rufus::CronLine do
|
|
207
245
|
|
208
246
|
nt('* * * * sun#2,sun#3', now).should == local(1970, 1, 18)
|
209
247
|
end
|
248
|
+
|
249
|
+
it 'computes the next time correctly when there is a L (last day of month)' do
|
250
|
+
|
251
|
+
nt('* * L * *', local(1970,1,1)).should == local(1970, 1, 31)
|
252
|
+
nt('* * L * *', local(1970,2,1)).should == local(1970, 2, 28)
|
253
|
+
nt('* * L * *', local(1972,2,1)).should == local(1972, 2, 29)
|
254
|
+
nt('* * L * *', local(1970,4,1)).should == local(1970, 4, 30)
|
255
|
+
end
|
210
256
|
end
|
211
257
|
|
212
258
|
describe '#matches?' do
|
@@ -264,6 +310,12 @@ describe Rufus::CronLine do
|
|
264
310
|
no_match '* * 13 * fri#2', utc(1970, 2, 20)
|
265
311
|
end
|
266
312
|
|
313
|
+
it 'matches correctly when there is a L involved' do
|
314
|
+
|
315
|
+
match '* * L * *', utc(1970, 1, 31)
|
316
|
+
no_match '* * L * *', utc(1970, 1, 30)
|
317
|
+
end
|
318
|
+
|
267
319
|
it 'matches correctly when there is a sun#2,sun#3 involved' do
|
268
320
|
|
269
321
|
no_match '* * * * sun#2,sun#3', local(1970, 1, 4)
|
data/spec/rtime_spec.rb
CHANGED
@@ -24,6 +24,15 @@ describe 'rufus/rtime' do
|
|
24
24
|
|
25
25
|
it 'parses duration strings' do
|
26
26
|
|
27
|
+
pts('-1.0d1.0w1.0d').should == -777600.0
|
28
|
+
pts('-1d1w1d').should == -777600.0
|
29
|
+
pts('-1w2d').should == -777600.0
|
30
|
+
pts('-1h10s').should == -3610.0
|
31
|
+
pts('-1h').should == -3600.0
|
32
|
+
pts('-5.').should == -5.0
|
33
|
+
pts('-2.5s').should == -2.5
|
34
|
+
pts('-1s').should == -1.0
|
35
|
+
pts('-500').should == -0.5
|
27
36
|
pts('').should == 0.0
|
28
37
|
pts('5.0').should == 5.0
|
29
38
|
pts('0.5').should == 0.5
|
@@ -39,6 +48,21 @@ describe 'rufus/rtime' do
|
|
39
48
|
pts('1w2d').should == 777600.0
|
40
49
|
pts('1d1w1d').should == 777600.0
|
41
50
|
pts('1.0d1.0w1.0d').should == 777600.0
|
51
|
+
|
52
|
+
pts('.5m').should == 30.0
|
53
|
+
pts('5.m').should == 300.0
|
54
|
+
pts('1m.5s').should == 60.5
|
55
|
+
pts('-.5m').should == -30.0
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'raises on wrong duration strings' do
|
59
|
+
|
60
|
+
lambda { pts('-') }.should raise_error(ArgumentError)
|
61
|
+
lambda { pts('h') }.should raise_error(ArgumentError)
|
62
|
+
lambda { pts('whatever') }.should raise_error(ArgumentError)
|
63
|
+
lambda { pts('hms') }.should raise_error(ArgumentError)
|
64
|
+
|
65
|
+
lambda { pts(' 1h ') }.should raise_error(ArgumentError)
|
42
66
|
end
|
43
67
|
|
44
68
|
it 'generates duration strings' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.18
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-03-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tzinfo
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: 0.3.23
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.3.23
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rake
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: rspec
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,7 +53,12 @@ dependencies:
|
|
43
53
|
version: 2.7.0
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 2.7.0
|
47
62
|
description: job scheduler for Ruby (at, cron, in and every jobs).
|
48
63
|
email:
|
49
64
|
- jmettraux@gmail.com
|
@@ -52,39 +67,38 @@ extensions: []
|
|
52
67
|
extra_rdoc_files: []
|
53
68
|
files:
|
54
69
|
- Rakefile
|
55
|
-
- lib/rufus
|
56
|
-
- lib/rufus/
|
57
|
-
- lib/rufus/sc/jobqueues.rb
|
58
|
-
- lib/rufus/sc/jobs.rb
|
59
|
-
- lib/rufus/sc/rtime.rb
|
70
|
+
- lib/rufus-scheduler.rb
|
71
|
+
- lib/rufus/scheduler.rb
|
60
72
|
- lib/rufus/sc/scheduler.rb
|
73
|
+
- lib/rufus/sc/rtime.rb
|
61
74
|
- lib/rufus/sc/version.rb
|
62
|
-
- lib/rufus/
|
63
|
-
- lib/rufus
|
64
|
-
-
|
65
|
-
-
|
66
|
-
- spec/
|
67
|
-
- spec/
|
68
|
-
- spec/
|
69
|
-
- spec/every_spec.rb
|
75
|
+
- lib/rufus/sc/cronline.rb
|
76
|
+
- lib/rufus/sc/jobs.rb
|
77
|
+
- lib/rufus/sc/jobqueues.rb
|
78
|
+
- lib/rufus/otime.rb
|
79
|
+
- spec/job_spec.rb
|
80
|
+
- spec/stress_schedule_unschedule_spec.rb
|
81
|
+
- spec/schedulable_spec.rb
|
70
82
|
- spec/exception_spec.rb
|
71
83
|
- spec/in_spec.rb
|
72
|
-
- spec/
|
73
|
-
- spec/
|
84
|
+
- spec/timeout_spec.rb
|
85
|
+
- spec/at_spec.rb
|
86
|
+
- spec/at_in_spec.rb
|
87
|
+
- spec/spec_base.rb
|
88
|
+
- spec/cronline_spec.rb
|
74
89
|
- spec/rtime_spec.rb
|
75
|
-
- spec/
|
90
|
+
- spec/mutex_spec.rb
|
76
91
|
- spec/scheduler_spec.rb
|
77
|
-
- spec/
|
78
|
-
- spec/
|
79
|
-
- spec/
|
80
|
-
- test/kjw.rb
|
92
|
+
- spec/blocking_spec.rb
|
93
|
+
- spec/every_spec.rb
|
94
|
+
- spec/cron_spec.rb
|
81
95
|
- test/t.rb
|
96
|
+
- test/kjw.rb
|
82
97
|
- rufus-scheduler.gemspec
|
83
98
|
- CHANGELOG.txt
|
84
|
-
- CREDITS.txt
|
85
|
-
- LICENSE.txt
|
86
|
-
- out.txt
|
87
99
|
- TODO.txt
|
100
|
+
- LICENSE.txt
|
101
|
+
- CREDITS.txt
|
88
102
|
- README.rdoc
|
89
103
|
homepage: http://github.com/jmettraux/rufus-scheduler
|
90
104
|
licenses: []
|
@@ -98,15 +112,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
98
112
|
- - ! '>='
|
99
113
|
- !ruby/object:Gem::Version
|
100
114
|
version: '0'
|
115
|
+
segments:
|
116
|
+
- 0
|
117
|
+
hash: 4543164608551708958
|
101
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
119
|
none: false
|
103
120
|
requirements:
|
104
121
|
- - ! '>='
|
105
122
|
- !ruby/object:Gem::Version
|
106
123
|
version: '0'
|
124
|
+
segments:
|
125
|
+
- 0
|
126
|
+
hash: 4543164608551708958
|
107
127
|
requirements: []
|
108
128
|
rubyforge_project: rufus
|
109
|
-
rubygems_version: 1.8.
|
129
|
+
rubygems_version: 1.8.24
|
110
130
|
signing_key:
|
111
131
|
specification_version: 3
|
112
132
|
summary: job scheduler for Ruby (at, cron, in and every jobs)
|
data/out.txt
DELETED