rufus-scheduler 1.0.13 → 1.0.14
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 +1 -0
- data/LICENSE.txt +1 -1
- data/README.txt +3 -1
- data/lib/rufus/scheduler/cronline.rb +88 -93
- data/lib/rufus/scheduler/jobs.rb +2 -7
- data/lib/rufus/scheduler/otime.rb +28 -33
- data/lib/rufus/scheduler/scheduler.rb +50 -45
- metadata +6 -4
data/CHANGELOG.txt
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
= rufus-scheduler CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
+
== rufus-scheduler - 1.0.14 released 2009/05/01
|
6
|
+
|
7
|
+
- bug #25746 : at/every/in scheduling stress issue.
|
8
|
+
Fixed by Klaas Jan Wierenga
|
9
|
+
|
10
|
+
|
5
11
|
== rufus-scheduler - 1.0.13 released 2009/02/02
|
6
12
|
|
7
13
|
- todo #23779 : removed lib/openwfe/ and restructured to lib/rufus/scheduler/
|
data/CREDITS.txt
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Copyright (c) 2005-
|
2
|
+
Copyright (c) 2005-2009, 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.txt
CHANGED
@@ -17,6 +17,8 @@ http://rubyforge.org/frs/?group_id=4812
|
|
17
17
|
|
18
18
|
== usage
|
19
19
|
|
20
|
+
(the rdoc is at http://rufus.rubyforge.org/rufus-scheduler/)
|
21
|
+
|
20
22
|
some examples :
|
21
23
|
|
22
24
|
require 'rubygems'
|
@@ -65,7 +67,7 @@ Apart from scheduling, There are also two interesting methods in this gem, they
|
|
65
67
|
Rufus.to_time_string 7 * 24 * 3600 # => '1w'
|
66
68
|
|
67
69
|
|
68
|
-
Something about the rufus-scheduler, threads and ActiveRecord connections :
|
70
|
+
Something about the rufus-scheduler, threads and ActiveRecord connections (warning : I'm mostly clueless about Rails) :
|
69
71
|
|
70
72
|
http://jmettraux.wordpress.com/2008/09/14/the-scheduler-and-the-active_record/
|
71
73
|
|
@@ -1,6 +1,5 @@
|
|
1
|
-
#
|
2
1
|
#--
|
3
|
-
# Copyright (c) 2006-
|
2
|
+
# Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
|
4
3
|
#
|
5
4
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
5
|
# of this software and associated documentation files (the "Software"), to deal
|
@@ -19,14 +18,10 @@
|
|
19
18
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
19
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
20
|
# THE SOFTWARE.
|
22
|
-
#++
|
23
21
|
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
24
|
|
25
|
-
#
|
26
|
-
# "made in Japan"
|
27
|
-
#
|
28
|
-
# John Mettraux at openwfe.org
|
29
|
-
#
|
30
25
|
|
31
26
|
module Rufus
|
32
27
|
|
@@ -166,124 +161,124 @@ module Rufus
|
|
166
161
|
|
167
162
|
private
|
168
163
|
|
169
|
-
|
170
|
-
|
164
|
+
#--
|
165
|
+
# adjust values to Ruby
|
166
|
+
#
|
167
|
+
#def adjust_arrays()
|
168
|
+
# @hours = @hours.collect { |h|
|
169
|
+
# if h == 24
|
170
|
+
# 0
|
171
|
+
# else
|
172
|
+
# h
|
173
|
+
# end
|
174
|
+
# } if @hours
|
175
|
+
# @weekdays = @weekdays.collect { |wd|
|
176
|
+
# wd - 1
|
177
|
+
# } if @weekdays
|
178
|
+
#end
|
179
|
+
#
|
180
|
+
# dead code, keeping it as a reminder
|
181
|
+
#++
|
182
|
+
|
183
|
+
WDS = %w[ sun mon tue wed thu fri sat ]
|
171
184
|
#
|
172
|
-
#
|
173
|
-
# @hours = @hours.collect { |h|
|
174
|
-
# if h == 24
|
175
|
-
# 0
|
176
|
-
# else
|
177
|
-
# h
|
178
|
-
# end
|
179
|
-
# } if @hours
|
180
|
-
# @weekdays = @weekdays.collect { |wd|
|
181
|
-
# wd - 1
|
182
|
-
# } if @weekdays
|
183
|
-
#end
|
184
|
-
#
|
185
|
-
# dead code, keeping it as a reminder
|
186
|
-
#++
|
187
|
-
|
188
|
-
WDS = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]
|
189
|
-
#
|
190
|
-
# used by parse_weekday()
|
191
|
-
|
192
|
-
def parse_weekdays (item)
|
193
|
-
|
194
|
-
item = item.downcase
|
195
|
-
|
196
|
-
WDS.each_with_index do |day, index|
|
197
|
-
item = item.gsub day, "#{index}"
|
198
|
-
end
|
185
|
+
# used by parse_weekday()
|
199
186
|
|
200
|
-
|
187
|
+
def parse_weekdays (item)
|
201
188
|
|
202
|
-
|
189
|
+
item = item.downcase
|
203
190
|
|
204
|
-
|
191
|
+
WDS.each_with_index do |day, index|
|
192
|
+
item = item.gsub day, "#{index}"
|
205
193
|
end
|
206
194
|
|
207
|
-
|
195
|
+
r = parse_item item, 0, 7
|
208
196
|
|
209
|
-
|
210
|
-
if item == "*"
|
211
|
-
return parse_list(item, min, max) \
|
212
|
-
if item.index(",")
|
213
|
-
return parse_range(item, min, max) \
|
214
|
-
if item.index("*") or item.index("-")
|
197
|
+
return r unless r.is_a?(Array)
|
215
198
|
|
216
|
-
|
199
|
+
r.collect { |e| e == 7 ? 0 : e }.uniq
|
200
|
+
end
|
217
201
|
|
218
|
-
|
219
|
-
i = max if i > max
|
202
|
+
def parse_item (item, min, max)
|
220
203
|
|
221
|
-
|
222
|
-
|
204
|
+
return nil \
|
205
|
+
if item == "*"
|
206
|
+
return parse_list(item, min, max) \
|
207
|
+
if item.index(",")
|
208
|
+
return parse_range(item, min, max) \
|
209
|
+
if item.index("*") or item.index("-")
|
223
210
|
|
224
|
-
|
211
|
+
i = Integer(item)
|
225
212
|
|
226
|
-
|
213
|
+
i = min if i < min
|
214
|
+
i = max if i > max
|
227
215
|
|
228
|
-
|
229
|
-
|
216
|
+
[ i ]
|
217
|
+
end
|
230
218
|
|
231
|
-
|
219
|
+
def parse_list (item, min, max)
|
232
220
|
|
233
|
-
|
234
|
-
j = item.index("/")
|
221
|
+
items = item.split(",")
|
235
222
|
|
236
|
-
|
223
|
+
items.inject([]) { |r, i| r.push(parse_range(i, min, max)) }.flatten
|
224
|
+
end
|
225
|
+
|
226
|
+
def parse_range (item, min, max)
|
237
227
|
|
238
|
-
|
228
|
+
i = item.index("-")
|
229
|
+
j = item.index("/")
|
239
230
|
|
240
|
-
|
231
|
+
return item.to_i if (not i and not j)
|
241
232
|
|
242
|
-
|
243
|
-
iend = -1
|
233
|
+
inc = 1
|
244
234
|
|
245
|
-
|
235
|
+
inc = Integer(item[j+1..-1]) if j
|
246
236
|
|
247
|
-
|
237
|
+
istart = -1
|
238
|
+
iend = -1
|
248
239
|
|
249
|
-
|
250
|
-
iend = Integer(item[i+1..j])
|
251
|
-
else
|
252
|
-
iend = Integer(item[i+1..-1])
|
253
|
-
end
|
240
|
+
if i
|
254
241
|
|
255
|
-
|
242
|
+
istart = Integer(item[0..i-1])
|
256
243
|
|
257
|
-
|
258
|
-
iend =
|
244
|
+
if j
|
245
|
+
iend = Integer(item[i+1..j])
|
246
|
+
else
|
247
|
+
iend = Integer(item[i+1..-1])
|
259
248
|
end
|
260
249
|
|
261
|
-
|
262
|
-
iend = max if iend > max
|
250
|
+
else # case */x
|
263
251
|
|
264
|
-
|
252
|
+
istart = min
|
253
|
+
iend = max
|
254
|
+
end
|
265
255
|
|
266
|
-
|
267
|
-
|
256
|
+
istart = min if istart < min
|
257
|
+
iend = max if iend > max
|
268
258
|
|
269
|
-
|
270
|
-
value = value + inc
|
271
|
-
break if value > iend
|
272
|
-
end
|
259
|
+
result = []
|
273
260
|
|
274
|
-
|
275
|
-
|
261
|
+
value = istart
|
262
|
+
loop do
|
276
263
|
|
277
|
-
|
278
|
-
|
264
|
+
result << value
|
265
|
+
value = value + inc
|
266
|
+
break if value > iend
|
279
267
|
end
|
280
268
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
269
|
+
result
|
270
|
+
end
|
271
|
+
|
272
|
+
def sub_match? value, values
|
273
|
+
values.nil? || values.include?(value)
|
274
|
+
end
|
275
|
+
|
276
|
+
def date_match? date
|
277
|
+
return false unless sub_match? date.day, @days
|
278
|
+
return false unless sub_match? date.month, @months
|
279
|
+
return false unless sub_match? date.wday, @weekdays
|
280
|
+
true
|
281
|
+
end
|
287
282
|
end
|
288
283
|
|
289
284
|
end
|
data/lib/rufus/scheduler/jobs.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
#
|
2
1
|
#--
|
3
2
|
# Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
|
4
3
|
#
|
@@ -19,14 +18,10 @@
|
|
19
18
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
19
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
20
|
# THE SOFTWARE.
|
22
|
-
#++
|
23
21
|
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
24
|
|
25
|
-
#
|
26
|
-
# "made in Japan"
|
27
|
-
#
|
28
|
-
# John Mettraux at openwfe.org
|
29
|
-
#
|
30
25
|
|
31
26
|
module Rufus
|
32
27
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
#
|
2
1
|
#--
|
3
2
|
# Copyright (c) 2005-2009, John Mettraux, jmettraux@gmail.com
|
4
3
|
#
|
@@ -19,14 +18,10 @@
|
|
19
18
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
19
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
20
|
# THE SOFTWARE.
|
22
|
-
#++
|
23
21
|
#
|
22
|
+
# Hecho en Costa Rica.
|
23
|
+
#++
|
24
24
|
|
25
|
-
#
|
26
|
-
# "hecho en Costa Rica"
|
27
|
-
#
|
28
|
-
# john.mettraux@openwfe.org
|
29
|
-
#
|
30
25
|
|
31
26
|
require 'date'
|
32
27
|
#require 'parsedate'
|
@@ -80,9 +75,9 @@ module Rufus
|
|
80
75
|
#
|
81
76
|
# Returns a Ruby time
|
82
77
|
#
|
83
|
-
def Rufus.to_ruby_time (
|
78
|
+
def Rufus.to_ruby_time (sdate)
|
84
79
|
|
85
|
-
DateTime.parse(
|
80
|
+
DateTime.parse(sdate)
|
86
81
|
end
|
87
82
|
|
88
83
|
#def Rufus.parse_date (date)
|
@@ -162,17 +157,17 @@ module Rufus
|
|
162
157
|
alias_method :parse_duration_string, :parse_time_string
|
163
158
|
end
|
164
159
|
|
165
|
-
|
160
|
+
#--
|
166
161
|
# Returns true if the character c is a digit
|
167
162
|
#
|
168
163
|
# (probably better served by a regex)
|
169
164
|
#
|
170
|
-
def Rufus.is_digit? (c)
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
165
|
+
#def Rufus.is_digit? (c)
|
166
|
+
# return false if not c.kind_of?(String)
|
167
|
+
# return false if c.length > 1
|
168
|
+
# (c >= '0' and c <= '9')
|
169
|
+
#end
|
170
|
+
#++
|
176
171
|
|
177
172
|
#
|
178
173
|
# conversion methods between Date[Time] and Time
|
@@ -352,24 +347,24 @@ module Rufus
|
|
352
347
|
|
353
348
|
protected
|
354
349
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
350
|
+
DURATIONS2M = [
|
351
|
+
[ 'y', 365 * 24 * 3600 ],
|
352
|
+
[ 'M', 30 * 24 * 3600 ],
|
353
|
+
[ 'w', 7 * 24 * 3600 ],
|
354
|
+
[ 'd', 24 * 3600 ],
|
355
|
+
[ 'h', 3600 ],
|
356
|
+
[ 'm', 60 ],
|
357
|
+
[ 's', 1 ]
|
358
|
+
]
|
359
|
+
DURATIONS2 = DURATIONS2M.dup
|
360
|
+
DURATIONS2.delete_at(1)
|
361
|
+
|
362
|
+
DURATIONS = DURATIONS2M.inject({}) do |r, (k, v)|
|
363
|
+
r[k] = v
|
364
|
+
r
|
365
|
+
end
|
371
366
|
|
372
|
-
|
367
|
+
DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
|
373
368
|
|
374
369
|
end
|
375
370
|
|
@@ -1,4 +1,3 @@
|
|
1
|
-
#
|
2
1
|
#--
|
3
2
|
# Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
|
4
3
|
#
|
@@ -19,14 +18,10 @@
|
|
19
18
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
19
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
20
|
# THE SOFTWARE.
|
22
|
-
#++
|
23
21
|
#
|
22
|
+
# Made in Japan.
|
23
|
+
#++
|
24
24
|
|
25
|
-
#
|
26
|
-
# "made in Japan"
|
27
|
-
#
|
28
|
-
# John Mettraux at openwfe.org
|
29
|
-
#
|
30
25
|
|
31
26
|
require 'thread'
|
32
27
|
require 'rufus/scheduler/otime'
|
@@ -339,7 +334,7 @@ module Rufus
|
|
339
334
|
#
|
340
335
|
class Scheduler
|
341
336
|
|
342
|
-
VERSION = '1.0.
|
337
|
+
VERSION = '1.0.14'
|
343
338
|
|
344
339
|
#
|
345
340
|
# By default, the precision is 0.250, with means the scheduler
|
@@ -378,8 +373,10 @@ module Rufus
|
|
378
373
|
@cron_jobs = {}
|
379
374
|
@non_cron_jobs = {}
|
380
375
|
|
381
|
-
@schedule_queue = Queue.new
|
382
|
-
@unschedule_queue = Queue.new
|
376
|
+
# @schedule_queue = Queue.new
|
377
|
+
# @unschedule_queue = Queue.new
|
378
|
+
|
379
|
+
@edit_queue = Queue.new
|
383
380
|
#
|
384
381
|
# sync between the step() method and the [un]schedule
|
385
382
|
# methods is done via these queues, no more mutex
|
@@ -655,7 +652,8 @@ module Rufus
|
|
655
652
|
b = to_block(params, &block)
|
656
653
|
job = CronJob.new(self, cron_id, cron_line, params, &b)
|
657
654
|
|
658
|
-
@schedule_queue << job
|
655
|
+
# @schedule_queue << job
|
656
|
+
@edit_queue << [ :schedule, job ]
|
659
657
|
|
660
658
|
job.job_id
|
661
659
|
end
|
@@ -677,7 +675,7 @@ module Rufus
|
|
677
675
|
#
|
678
676
|
def unschedule (job_id)
|
679
677
|
|
680
|
-
@
|
678
|
+
@edit_queue << [ :unschedule, job_id ]
|
681
679
|
end
|
682
680
|
|
683
681
|
#
|
@@ -842,14 +840,16 @@ module Rufus
|
|
842
840
|
|
843
841
|
job.trigger() unless params[:discard_past]
|
844
842
|
|
845
|
-
@non_cron_jobs
|
843
|
+
# change to @non_cron_jobs must be executed on scheduler thread (in step_schedule)
|
844
|
+
# @non_cron_jobs.delete(job.job_id) # just to be sure
|
846
845
|
|
847
846
|
return nil
|
848
847
|
end
|
849
848
|
|
850
|
-
@non_cron_jobs
|
849
|
+
# change to @non_cron_jobs must be executed on scheduler thread (in step_schedule)
|
850
|
+
# @non_cron_jobs[job.job_id] = job
|
851
851
|
|
852
|
-
@
|
852
|
+
@edit_queue << [ :schedule, job ]
|
853
853
|
|
854
854
|
job.job_id
|
855
855
|
end
|
@@ -924,55 +924,60 @@ module Rufus
|
|
924
924
|
#
|
925
925
|
def step
|
926
926
|
|
927
|
-
|
928
|
-
#
|
929
|
-
#
|
927
|
+
step_edit
|
928
|
+
# handle ops in the edit_queue
|
929
|
+
# this ensures that schedule and unschedule requests are processed
|
930
|
+
# in order
|
930
931
|
|
931
932
|
step_trigger
|
932
933
|
# triggers eligible jobs
|
933
934
|
|
934
|
-
step_schedule
|
935
|
-
# schedule new jobs
|
936
|
-
|
937
935
|
# done.
|
938
936
|
end
|
939
937
|
|
940
938
|
#
|
941
|
-
# unschedules
|
942
|
-
#
|
943
|
-
def step_unschedule
|
944
|
-
|
945
|
-
loop do
|
946
|
-
|
947
|
-
break if @unschedule_queue.empty?
|
948
|
-
|
949
|
-
do_unschedule(@unschedule_queue.pop)
|
950
|
-
end
|
951
|
-
end
|
952
|
-
|
953
|
-
#
|
954
|
-
# adds every job waiting in the @schedule_queue to
|
955
|
-
# either @pending_jobs or @cron_jobs.
|
939
|
+
# schedules or unschedules job in the edit_queue
|
940
|
+
# schedule's and unschedule are processed in order
|
956
941
|
#
|
957
|
-
def
|
958
|
-
|
942
|
+
def step_edit
|
959
943
|
loop do
|
944
|
+
break if @edit_queue.empty?
|
945
|
+
op, j = @edit_queue.pop
|
960
946
|
|
961
|
-
|
962
|
-
|
963
|
-
|
947
|
+
case op
|
948
|
+
when :schedule
|
949
|
+
if j.is_a?(CronJob)
|
964
950
|
|
965
|
-
|
951
|
+
@cron_jobs[j.job_id] = j
|
966
952
|
|
967
|
-
|
953
|
+
else # it's an 'at' job
|
968
954
|
|
969
|
-
|
955
|
+
# add job to @non_cron_jobs
|
956
|
+
@non_cron_jobs[j.job_id] = j
|
957
|
+
push_pending_job j
|
970
958
|
|
971
|
-
|
959
|
+
end
|
960
|
+
when :unschedule
|
961
|
+
do_unschedule(j)
|
962
|
+
else
|
963
|
+
raise ArgumentError
|
972
964
|
end
|
973
965
|
end
|
974
966
|
end
|
975
967
|
|
968
|
+
#
|
969
|
+
# unschedules jobs in the unschedule_queue
|
970
|
+
#
|
971
|
+
# def step_unschedule
|
972
|
+
#
|
973
|
+
# loop do
|
974
|
+
#
|
975
|
+
# break if @unschedule_queue.empty?
|
976
|
+
#
|
977
|
+
# do_unschedule(@unschedule_queue.pop)
|
978
|
+
# end
|
979
|
+
# end
|
980
|
+
|
976
981
|
#
|
977
982
|
# triggers every eligible pending (at or every) jobs, then every eligible
|
978
983
|
# cron jobs.
|
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: 1.0.
|
4
|
+
version: 1.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-01 00:00:00 +09:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -37,6 +37,8 @@ files:
|
|
37
37
|
- README.txt
|
38
38
|
has_rdoc: true
|
39
39
|
homepage: http://openwferu.rubyforge.org/scheduler.html
|
40
|
+
licenses: []
|
41
|
+
|
40
42
|
post_install_message:
|
41
43
|
rdoc_options: []
|
42
44
|
|
@@ -57,9 +59,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
57
59
|
requirements: []
|
58
60
|
|
59
61
|
rubyforge_project: rufus
|
60
|
-
rubygems_version: 1.3.
|
62
|
+
rubygems_version: 1.3.2
|
61
63
|
signing_key:
|
62
|
-
specification_version:
|
64
|
+
specification_version: 3
|
63
65
|
summary: scheduler for Ruby (at, cron and every jobs), formerly known as 'openwferu-scheduler'
|
64
66
|
test_files:
|
65
67
|
- test/test.rb
|