rufus-scheduler 3.2.0 → 3.3.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.
- checksums.yaml +7 -0
- data/CHANGELOG.txt +24 -0
- data/CREDITS.txt +12 -0
- data/LICENSE.txt +1 -1
- data/Makefile +23 -0
- data/README.md +65 -20
- data/fail18.txt +12 -0
- data/lib/rufus/scheduler/cronline.rb +113 -88
- data/lib/rufus/scheduler/job_array.rb +8 -4
- data/lib/rufus/scheduler/jobs.rb +56 -35
- data/lib/rufus/scheduler/locks.rb +2 -2
- data/lib/rufus/scheduler/util.rb +33 -48
- data/lib/rufus/scheduler/zotime.rb +348 -66
- data/lib/rufus/scheduler.rb +19 -10
- data/pics.txt +15 -0
- data/rufus-scheduler.gemspec +2 -4
- metadata +25 -48
- data/Rakefile +0 -83
- data/lib/rufus/scheduler/zones.rb +0 -175
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2006-
|
|
2
|
+
# Copyright (c) 2006-2016, 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
|
|
@@ -36,6 +36,7 @@ class Rufus::Scheduler
|
|
|
36
36
|
# The string used for creating this cronline instance.
|
|
37
37
|
#
|
|
38
38
|
attr_reader :original
|
|
39
|
+
attr_reader :original_timezone
|
|
39
40
|
|
|
40
41
|
attr_reader :seconds
|
|
41
42
|
attr_reader :minutes
|
|
@@ -53,10 +54,15 @@ class Rufus::Scheduler
|
|
|
53
54
|
) unless line.is_a?(String)
|
|
54
55
|
|
|
55
56
|
@original = line
|
|
57
|
+
@original_timezone = nil
|
|
56
58
|
|
|
57
59
|
items = line.split
|
|
58
60
|
|
|
59
|
-
@timezone =
|
|
61
|
+
if @timezone = ZoTime.get_tzone(items.last)
|
|
62
|
+
@original_timezone = items.pop
|
|
63
|
+
else
|
|
64
|
+
@timezone = ZoTime.get_tzone(:current)
|
|
65
|
+
end
|
|
60
66
|
|
|
61
67
|
fail ArgumentError.new(
|
|
62
68
|
"not a valid cronline : '#{line}'"
|
|
@@ -67,7 +73,7 @@ class Rufus::Scheduler
|
|
|
67
73
|
@seconds = offset == 1 ? parse_item(items[0], 0, 59) : [ 0 ]
|
|
68
74
|
@minutes = parse_item(items[0 + offset], 0, 59)
|
|
69
75
|
@hours = parse_item(items[1 + offset], 0, 24)
|
|
70
|
-
@days = parse_item(items[2 + offset],
|
|
76
|
+
@days = parse_item(items[2 + offset], -30, 31)
|
|
71
77
|
@months = parse_item(items[3 + offset], 1, 12)
|
|
72
78
|
@weekdays, @monthdays = parse_weekdays(items[4 + offset])
|
|
73
79
|
|
|
@@ -77,18 +83,26 @@ class Rufus::Scheduler
|
|
|
77
83
|
"invalid cronline: '#{line}'"
|
|
78
84
|
) if es && es.find { |e| ! e.is_a?(Fixnum) }
|
|
79
85
|
end
|
|
86
|
+
|
|
87
|
+
if @days && @days.include?(0) # gh-221
|
|
88
|
+
|
|
89
|
+
fail ArgumentError.new('invalid day 0 in cronline')
|
|
90
|
+
end
|
|
80
91
|
end
|
|
81
92
|
|
|
82
93
|
# Returns true if the given time matches this cron line.
|
|
83
94
|
#
|
|
84
95
|
def matches?(time)
|
|
85
96
|
|
|
86
|
-
|
|
97
|
+
# FIXME Don't create a new ZoTime if time is already a ZoTime in same
|
|
98
|
+
# zone ...
|
|
99
|
+
# Wait, this seems only used in specs...
|
|
100
|
+
t = ZoTime.new(time.to_f, @timezone)
|
|
87
101
|
|
|
88
|
-
return false unless sub_match?(
|
|
89
|
-
return false unless sub_match?(
|
|
90
|
-
return false unless sub_match?(
|
|
91
|
-
return false unless date_match?(
|
|
102
|
+
return false unless sub_match?(t, :sec, @seconds)
|
|
103
|
+
return false unless sub_match?(t, :min, @minutes)
|
|
104
|
+
return false unless sub_match?(t, :hour, @hours)
|
|
105
|
+
return false unless date_match?(t)
|
|
92
106
|
true
|
|
93
107
|
end
|
|
94
108
|
|
|
@@ -119,36 +133,36 @@ class Rufus::Scheduler
|
|
|
119
133
|
#
|
|
120
134
|
# (Thanks to K Liu for the note and the examples)
|
|
121
135
|
#
|
|
122
|
-
def next_time(from=
|
|
136
|
+
def next_time(from=ZoTime.now)
|
|
123
137
|
|
|
124
|
-
|
|
125
|
-
|
|
138
|
+
nt = nil
|
|
139
|
+
zt = ZoTime.new(from.to_i + 1, @timezone)
|
|
126
140
|
|
|
127
141
|
loop do
|
|
128
142
|
|
|
129
|
-
|
|
143
|
+
nt = zt.dup
|
|
130
144
|
|
|
131
|
-
unless date_match?(
|
|
132
|
-
|
|
145
|
+
unless date_match?(nt)
|
|
146
|
+
zt.add((24 - nt.hour) * 3600 - nt.min * 60 - nt.sec)
|
|
133
147
|
next
|
|
134
148
|
end
|
|
135
|
-
unless sub_match?(
|
|
136
|
-
|
|
149
|
+
unless sub_match?(nt, :hour, @hours)
|
|
150
|
+
zt.add((60 - nt.min) * 60 - nt.sec)
|
|
137
151
|
next
|
|
138
152
|
end
|
|
139
|
-
unless sub_match?(
|
|
140
|
-
|
|
153
|
+
unless sub_match?(nt, :min, @minutes)
|
|
154
|
+
zt.add(60 - nt.sec)
|
|
141
155
|
next
|
|
142
156
|
end
|
|
143
|
-
unless sub_match?(
|
|
144
|
-
|
|
157
|
+
unless sub_match?(nt, :sec, @seconds)
|
|
158
|
+
zt.add(next_second(nt))
|
|
145
159
|
next
|
|
146
160
|
end
|
|
147
161
|
|
|
148
162
|
break
|
|
149
163
|
end
|
|
150
164
|
|
|
151
|
-
|
|
165
|
+
nt
|
|
152
166
|
end
|
|
153
167
|
|
|
154
168
|
# Returns the previous time the cronline matched. It's like next_time, but
|
|
@@ -156,41 +170,41 @@ class Rufus::Scheduler
|
|
|
156
170
|
#
|
|
157
171
|
def previous_time(from=Time.now)
|
|
158
172
|
|
|
159
|
-
|
|
160
|
-
|
|
173
|
+
pt = nil
|
|
174
|
+
zt = ZoTime.new(from.to_i - 1, @timezone)
|
|
161
175
|
|
|
162
176
|
loop do
|
|
163
177
|
|
|
164
|
-
|
|
178
|
+
pt = zt.dup
|
|
165
179
|
|
|
166
|
-
unless date_match?(
|
|
167
|
-
|
|
180
|
+
unless date_match?(pt)
|
|
181
|
+
zt.substract(pt.hour * 3600 + pt.min * 60 + pt.sec + 1)
|
|
168
182
|
next
|
|
169
183
|
end
|
|
170
|
-
unless sub_match?(
|
|
171
|
-
|
|
184
|
+
unless sub_match?(pt, :hour, @hours)
|
|
185
|
+
zt.substract(pt.min * 60 + pt.sec + 1)
|
|
172
186
|
next
|
|
173
187
|
end
|
|
174
|
-
unless sub_match?(
|
|
175
|
-
|
|
188
|
+
unless sub_match?(pt, :min, @minutes)
|
|
189
|
+
zt.substract(pt.sec + 1)
|
|
176
190
|
next
|
|
177
191
|
end
|
|
178
|
-
unless sub_match?(
|
|
179
|
-
|
|
192
|
+
unless sub_match?(pt, :sec, @seconds)
|
|
193
|
+
zt.substract(prev_second(pt))
|
|
180
194
|
next
|
|
181
195
|
end
|
|
182
196
|
|
|
183
197
|
break
|
|
184
198
|
end
|
|
185
199
|
|
|
186
|
-
|
|
200
|
+
pt
|
|
187
201
|
end
|
|
188
202
|
|
|
189
203
|
# Returns an array of 6 arrays (seconds, minutes, hours, days,
|
|
190
204
|
# months, weekdays).
|
|
191
|
-
# This method is used by the cronline
|
|
205
|
+
# This method is mostly used by the cronline specs.
|
|
192
206
|
#
|
|
193
|
-
def
|
|
207
|
+
def to_a
|
|
194
208
|
|
|
195
209
|
[
|
|
196
210
|
toa(@seconds),
|
|
@@ -200,9 +214,10 @@ class Rufus::Scheduler
|
|
|
200
214
|
toa(@months),
|
|
201
215
|
toa(@weekdays),
|
|
202
216
|
toa(@monthdays),
|
|
203
|
-
@timezone
|
|
217
|
+
@timezone.name
|
|
204
218
|
]
|
|
205
219
|
end
|
|
220
|
+
alias to_array to_a
|
|
206
221
|
|
|
207
222
|
# Returns a quickly computed approximation of the frequency for this
|
|
208
223
|
# cron line.
|
|
@@ -259,7 +274,9 @@ class Rufus::Scheduler
|
|
|
259
274
|
break if delta <= 1
|
|
260
275
|
break if delta <= 60 && @seconds && @seconds.size == 1
|
|
261
276
|
|
|
277
|
+
#st = Time.now
|
|
262
278
|
t1 = next_time(t0)
|
|
279
|
+
#p Time.now - st
|
|
263
280
|
d = t1 - t0
|
|
264
281
|
delta = d if d < delta
|
|
265
282
|
|
|
@@ -313,39 +330,38 @@ class Rufus::Scheduler
|
|
|
313
330
|
|
|
314
331
|
WEEKDAYS = %w[ sun mon tue wed thu fri sat ]
|
|
315
332
|
DAY_S = 24 * 3600
|
|
316
|
-
WEEK_S = 7 * DAY_S
|
|
317
333
|
|
|
318
334
|
def parse_weekdays(item)
|
|
319
335
|
|
|
320
336
|
return nil if item == '*'
|
|
321
337
|
|
|
322
|
-
items = item.downcase.split(',')
|
|
323
|
-
|
|
324
338
|
weekdays = nil
|
|
325
339
|
monthdays = nil
|
|
326
340
|
|
|
327
|
-
|
|
341
|
+
item.downcase.split(',').each do |it|
|
|
328
342
|
|
|
329
|
-
|
|
343
|
+
WEEKDAYS.each_with_index { |a, i| it.gsub!(/#{a}/, i.to_s) }
|
|
344
|
+
|
|
345
|
+
it = it.gsub(/([^#])l/, '\1#-1')
|
|
346
|
+
# "5L" == "5#-1" == the last Friday
|
|
347
|
+
|
|
348
|
+
if m = it.match(/\A(.+)#(l|-?[12345])\z/)
|
|
330
349
|
|
|
331
350
|
fail ArgumentError.new(
|
|
332
351
|
"ranges are not supported for monthdays (#{it})"
|
|
333
352
|
) if m[1].index('-')
|
|
334
353
|
|
|
335
|
-
|
|
354
|
+
it = it.gsub(/#l/, '#-1')
|
|
336
355
|
|
|
337
|
-
(monthdays ||= []) <<
|
|
356
|
+
(monthdays ||= []) << it
|
|
338
357
|
|
|
339
358
|
else
|
|
340
359
|
|
|
341
|
-
expr = it.dup
|
|
342
|
-
WEEKDAYS.each_with_index { |a, i| expr.gsub!(/#{a}/, i.to_s) }
|
|
343
|
-
|
|
344
360
|
fail ArgumentError.new(
|
|
345
|
-
"invalid weekday expression (#{
|
|
346
|
-
) if
|
|
361
|
+
"invalid weekday expression (#{item})"
|
|
362
|
+
) if it !~ /\A0*[0-7](-0*[0-7])?\z/
|
|
347
363
|
|
|
348
|
-
its =
|
|
364
|
+
its = it.index('-') ? parse_range(it, 0, 7) : [ Integer(it) ]
|
|
349
365
|
its = its.collect { |i| i == 7 ? 0 : i }
|
|
350
366
|
|
|
351
367
|
(weekdays ||= []).concat(its)
|
|
@@ -372,7 +388,7 @@ class Rufus::Scheduler
|
|
|
372
388
|
Set.new(r)
|
|
373
389
|
end
|
|
374
390
|
|
|
375
|
-
RANGE_REGEX =
|
|
391
|
+
RANGE_REGEX = /\A(\*|-?\d{1,2})(?:-(-?\d{1,2}))?(?:\/(\d{1,2}))?\z/
|
|
376
392
|
|
|
377
393
|
def parse_range(item, min, max)
|
|
378
394
|
|
|
@@ -386,8 +402,10 @@ class Rufus::Scheduler
|
|
|
386
402
|
"cannot parse #{item.inspect}"
|
|
387
403
|
) unless m
|
|
388
404
|
|
|
405
|
+
mmin = min == -30 ? 1 : min # days
|
|
406
|
+
|
|
389
407
|
sta = m[1]
|
|
390
|
-
sta = sta == '*' ?
|
|
408
|
+
sta = sta == '*' ? mmin : sta.to_i
|
|
391
409
|
|
|
392
410
|
edn = m[2]
|
|
393
411
|
edn = edn ? edn.to_i : sta
|
|
@@ -396,16 +414,28 @@ class Rufus::Scheduler
|
|
|
396
414
|
inc = m[3]
|
|
397
415
|
inc = inc ? inc.to_i : 1
|
|
398
416
|
|
|
417
|
+
fail ArgumentError.new(
|
|
418
|
+
"#{item.inspect} positive/negative ranges not allowed"
|
|
419
|
+
) if (sta < 0 && edn > 0) || (sta > 0 && edn < 0)
|
|
420
|
+
|
|
421
|
+
fail ArgumentError.new(
|
|
422
|
+
"#{item.inspect} descending day ranges not allowed"
|
|
423
|
+
) if min == -30 && sta > edn
|
|
424
|
+
|
|
399
425
|
fail ArgumentError.new(
|
|
400
426
|
"#{item.inspect} is not in range #{min}..#{max}"
|
|
401
427
|
) if sta < min || edn > max
|
|
402
428
|
|
|
429
|
+
fail ArgumentError.new(
|
|
430
|
+
"#{item.inspect} increment must be greater than zero"
|
|
431
|
+
) if inc == 0
|
|
432
|
+
|
|
403
433
|
r = []
|
|
404
434
|
val = sta
|
|
405
435
|
|
|
406
436
|
loop do
|
|
407
437
|
v = val
|
|
408
|
-
v = 0 if max == 24 && v == 24
|
|
438
|
+
v = 0 if max == 24 && v == 24 # hours
|
|
409
439
|
r << v
|
|
410
440
|
break if inc == 1 && val == edn
|
|
411
441
|
val += inc
|
|
@@ -416,57 +446,52 @@ class Rufus::Scheduler
|
|
|
416
446
|
r.uniq
|
|
417
447
|
end
|
|
418
448
|
|
|
449
|
+
# FIXME: Eventually split into day_match?, hour_match? and monthdays_match?o
|
|
450
|
+
#
|
|
419
451
|
def sub_match?(time, accessor, values)
|
|
420
452
|
|
|
421
|
-
value = time.send(accessor)
|
|
422
|
-
|
|
423
453
|
return true if values.nil?
|
|
424
|
-
return true if values.include?('L') && (time + DAY_S).day == 1
|
|
425
454
|
|
|
426
|
-
|
|
455
|
+
value = time.send(accessor)
|
|
427
456
|
|
|
428
|
-
|
|
429
|
-
end
|
|
457
|
+
if accessor == :day
|
|
430
458
|
|
|
431
|
-
|
|
459
|
+
values.each do |v|
|
|
460
|
+
return true if v == 'L' && (time + DAY_S).day == 1
|
|
461
|
+
return true if v.to_i < 0 && (time + (1 - v) * DAY_S).day == 1
|
|
462
|
+
end
|
|
463
|
+
end
|
|
432
464
|
|
|
433
|
-
|
|
465
|
+
if accessor == :hour
|
|
434
466
|
|
|
435
|
-
|
|
467
|
+
return true if value == 0 && values.include?(24)
|
|
468
|
+
end
|
|
436
469
|
|
|
437
|
-
|
|
438
|
-
end
|
|
470
|
+
if accessor == :monthdays
|
|
439
471
|
|
|
440
|
-
|
|
472
|
+
return true if (values & value).any?
|
|
473
|
+
end
|
|
441
474
|
|
|
442
|
-
|
|
443
|
-
return false unless sub_match?(date, :month, @months)
|
|
444
|
-
return false unless sub_match?(date, :wday, @weekdays)
|
|
445
|
-
return false unless monthday_match?(date, @monthdays)
|
|
446
|
-
true
|
|
475
|
+
values.include?(value)
|
|
447
476
|
end
|
|
448
477
|
|
|
449
|
-
def
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
pos = pos + 1
|
|
458
|
-
end
|
|
459
|
-
|
|
460
|
-
neg = -1
|
|
461
|
-
d = date.dup
|
|
478
|
+
# def monthday_match?(zt, values)
|
|
479
|
+
#
|
|
480
|
+
# return true if values.nil?
|
|
481
|
+
#
|
|
482
|
+
# today_values = monthdays(zt)
|
|
483
|
+
#
|
|
484
|
+
# (today_values & values).any?
|
|
485
|
+
# end
|
|
462
486
|
|
|
463
|
-
|
|
464
|
-
d = d + WEEK_S
|
|
465
|
-
break if d.month != date.month
|
|
466
|
-
neg = neg - 1
|
|
467
|
-
end
|
|
487
|
+
def date_match?(zt)
|
|
468
488
|
|
|
469
|
-
|
|
489
|
+
return false unless sub_match?(zt, :day, @days)
|
|
490
|
+
return false unless sub_match?(zt, :month, @months)
|
|
491
|
+
return false unless sub_match?(zt, :wday, @weekdays)
|
|
492
|
+
#return false unless monthday_match?(zt, @monthdays)
|
|
493
|
+
return false unless sub_match?(zt, :monthdays, @monthdays)
|
|
494
|
+
true
|
|
470
495
|
end
|
|
471
496
|
end
|
|
472
497
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2006-
|
|
2
|
+
# Copyright (c) 2006-2016, 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
|
|
@@ -53,10 +53,14 @@ module Rufus
|
|
|
53
53
|
|
|
54
54
|
def each(now, &block)
|
|
55
55
|
|
|
56
|
-
to_a.sort_by
|
|
56
|
+
to_a.sort_by do |job|
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
job.next_time || (now + 1)
|
|
59
|
+
|
|
60
|
+
end.each do |job|
|
|
61
|
+
|
|
62
|
+
nt = job.next_time
|
|
63
|
+
break if ( ! nt) || (nt > now)
|
|
60
64
|
|
|
61
65
|
block.call(job)
|
|
62
66
|
end
|
data/lib/rufus/scheduler/jobs.rb
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2006-
|
|
2
|
+
# Copyright (c) 2006-2016, 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
|
|
@@ -53,6 +53,10 @@ module Rufus
|
|
|
53
53
|
#
|
|
54
54
|
attr_accessor :next_time
|
|
55
55
|
|
|
56
|
+
# previous "next trigger time"
|
|
57
|
+
#
|
|
58
|
+
attr_accessor :previous_time
|
|
59
|
+
|
|
56
60
|
# anything with a #call(job[, timet]) method,
|
|
57
61
|
# what gets actually triggered
|
|
58
62
|
#
|
|
@@ -82,7 +86,7 @@ module Rufus
|
|
|
82
86
|
nil
|
|
83
87
|
end
|
|
84
88
|
|
|
85
|
-
@scheduled_at =
|
|
89
|
+
@scheduled_at = Rufus::Scheduler::ZoTime.now
|
|
86
90
|
@unscheduled_at = nil
|
|
87
91
|
@last_time = nil
|
|
88
92
|
|
|
@@ -117,29 +121,25 @@ module Rufus
|
|
|
117
121
|
|
|
118
122
|
def trigger(time)
|
|
119
123
|
|
|
124
|
+
@previous_time = @next_time
|
|
120
125
|
set_next_time(time)
|
|
121
126
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
running?
|
|
125
|
-
)
|
|
126
|
-
return if (
|
|
127
|
-
callback(:confirm_lock, time) &&
|
|
128
|
-
callback(:on_pre_trigger, time)
|
|
129
|
-
) == false
|
|
127
|
+
do_trigger(time)
|
|
128
|
+
end
|
|
130
129
|
|
|
131
|
-
|
|
130
|
+
# Trigger the job right now, off of its schedule.
|
|
131
|
+
#
|
|
132
|
+
# Done in collaboration with Piavka in
|
|
133
|
+
# https://github.com/jmettraux/rufus-scheduler/issues/214
|
|
134
|
+
#
|
|
135
|
+
def trigger_off_schedule(time=Rufus::Scheduler::ZoTime.now)
|
|
132
136
|
|
|
133
|
-
|
|
134
|
-
do_trigger(time)
|
|
135
|
-
else
|
|
136
|
-
do_trigger_in_thread(time)
|
|
137
|
-
end
|
|
137
|
+
do_trigger(time)
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
def unschedule
|
|
141
141
|
|
|
142
|
-
@unscheduled_at =
|
|
142
|
+
@unscheduled_at = Rufus::Scheduler::ZoTime.now
|
|
143
143
|
end
|
|
144
144
|
|
|
145
145
|
def threads
|
|
@@ -199,7 +199,7 @@ module Rufus
|
|
|
199
199
|
#
|
|
200
200
|
def call(do_rescue=false)
|
|
201
201
|
|
|
202
|
-
do_call(
|
|
202
|
+
do_call(Rufus::Scheduler::ZoTime.now, do_rescue)
|
|
203
203
|
end
|
|
204
204
|
|
|
205
205
|
protected
|
|
@@ -246,7 +246,27 @@ module Rufus
|
|
|
246
246
|
|
|
247
247
|
def do_trigger(time)
|
|
248
248
|
|
|
249
|
-
|
|
249
|
+
return if (
|
|
250
|
+
opts[:overlap] == false &&
|
|
251
|
+
running?
|
|
252
|
+
)
|
|
253
|
+
return if (
|
|
254
|
+
callback(:confirm_lock, time) &&
|
|
255
|
+
callback(:on_pre_trigger, time)
|
|
256
|
+
) == false
|
|
257
|
+
|
|
258
|
+
@count += 1
|
|
259
|
+
|
|
260
|
+
if opts[:blocking]
|
|
261
|
+
trigger_now(time)
|
|
262
|
+
else
|
|
263
|
+
trigger_queue(time)
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def trigger_now(time)
|
|
268
|
+
|
|
269
|
+
t = Rufus::Scheduler::ZoTime.now
|
|
250
270
|
# if there are mutexes, t might be really bigger than time
|
|
251
271
|
|
|
252
272
|
Thread.current[:rufus_scheduler_job] = self
|
|
@@ -260,7 +280,7 @@ module Rufus
|
|
|
260
280
|
ensure
|
|
261
281
|
|
|
262
282
|
@last_work_time =
|
|
263
|
-
|
|
283
|
+
Rufus::Scheduler::ZoTime.now - Thread.current[:rufus_scheduler_time]
|
|
264
284
|
@mean_work_time =
|
|
265
285
|
((@count - 1) * @mean_work_time + @last_work_time) / @count
|
|
266
286
|
|
|
@@ -297,7 +317,7 @@ module Rufus
|
|
|
297
317
|
begin
|
|
298
318
|
|
|
299
319
|
(job.opts[:mutex] || []).reduce(
|
|
300
|
-
lambda { job.
|
|
320
|
+
lambda { job.trigger_now(time) }
|
|
301
321
|
) do |b, m|
|
|
302
322
|
lambda { mutex(m).synchronize { b.call } }
|
|
303
323
|
end.call
|
|
@@ -316,9 +336,11 @@ module Rufus
|
|
|
316
336
|
# but since it has to be done as quickly as possible.
|
|
317
337
|
# So, whoever is running first (scheduler thread vs job thread)
|
|
318
338
|
# sets this information
|
|
339
|
+
|
|
340
|
+
thread
|
|
319
341
|
end
|
|
320
342
|
|
|
321
|
-
def
|
|
343
|
+
def trigger_queue(time)
|
|
322
344
|
|
|
323
345
|
threads = @scheduler.work_threads
|
|
324
346
|
|
|
@@ -418,12 +440,12 @@ module Rufus
|
|
|
418
440
|
|
|
419
441
|
return (@first_at = nil) if first == nil
|
|
420
442
|
|
|
421
|
-
n0 =
|
|
443
|
+
n0 = Rufus::Scheduler::ZoTime.now
|
|
422
444
|
n1 = n0 + 0.003
|
|
423
445
|
|
|
424
446
|
first = n0 if first == :now || first == :immediately || first == 0
|
|
425
447
|
|
|
426
|
-
@first_at =
|
|
448
|
+
@first_at = ZoTime.make(first)
|
|
427
449
|
@first_at = n1 if @first_at >= n0 && @first_at < n1
|
|
428
450
|
|
|
429
451
|
fail ArgumentError.new(
|
|
@@ -436,12 +458,13 @@ module Rufus
|
|
|
436
458
|
|
|
437
459
|
def last_at=(last)
|
|
438
460
|
|
|
439
|
-
|
|
461
|
+
#@last_at = last ? Rufus::Scheduler.parse_to_time(last) : nil
|
|
462
|
+
@last_at = last ? ZoTime.make(last) : nil
|
|
440
463
|
|
|
441
464
|
fail ArgumentError.new(
|
|
442
465
|
"cannot set last[_at|_in] in the past: " +
|
|
443
466
|
"#{last.inspect} -> #{@last_at.inspect}"
|
|
444
|
-
) if last && @last_at <
|
|
467
|
+
) if last && @last_at < Rufus::Scheduler::ZoTime.now
|
|
445
468
|
|
|
446
469
|
@last_at
|
|
447
470
|
end
|
|
@@ -453,7 +476,7 @@ module Rufus
|
|
|
453
476
|
return (@next_time = nil) if @times && @times < 1
|
|
454
477
|
return (@next_time = nil) if @last_at && time >= @last_at
|
|
455
478
|
#
|
|
456
|
-
#
|
|
479
|
+
# It keeps jobs one step too much in @jobs, but it's OK
|
|
457
480
|
|
|
458
481
|
super
|
|
459
482
|
|
|
@@ -462,7 +485,7 @@ module Rufus
|
|
|
462
485
|
|
|
463
486
|
def pause
|
|
464
487
|
|
|
465
|
-
@paused_at =
|
|
488
|
+
@paused_at = Rufus::Scheduler::ZoTime.now
|
|
466
489
|
end
|
|
467
490
|
|
|
468
491
|
def resume
|
|
@@ -513,9 +536,7 @@ module Rufus
|
|
|
513
536
|
|
|
514
537
|
def first_at=(first)
|
|
515
538
|
|
|
516
|
-
super
|
|
517
|
-
|
|
518
|
-
@next_time = @first_at
|
|
539
|
+
@next_time = super
|
|
519
540
|
end
|
|
520
541
|
end
|
|
521
542
|
|
|
@@ -543,10 +564,10 @@ module Rufus
|
|
|
543
564
|
|
|
544
565
|
return if is_post
|
|
545
566
|
|
|
546
|
-
n =
|
|
567
|
+
n = Rufus::Scheduler::ZoTime.now
|
|
547
568
|
|
|
548
569
|
@next_time =
|
|
549
|
-
if @first_at == nil || @first_at < n
|
|
570
|
+
if @first_at == nil || @first_at < (n - @scheduler.frequency)
|
|
550
571
|
nt = (@next_time || trigger_time || n) + @frequency
|
|
551
572
|
nt > n ? nt : (trigger_time || n) + @frequency
|
|
552
573
|
else
|
|
@@ -584,10 +605,10 @@ module Rufus
|
|
|
584
605
|
|
|
585
606
|
@next_time =
|
|
586
607
|
if is_post
|
|
587
|
-
|
|
608
|
+
Rufus::Scheduler::ZoTime.now + @interval
|
|
588
609
|
elsif trigger_time.nil?
|
|
589
610
|
if @first_at == nil || @first_at < Time.now
|
|
590
|
-
|
|
611
|
+
Rufus::Scheduler::ZoTime.now + @interval
|
|
591
612
|
else
|
|
592
613
|
@first_at
|
|
593
614
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#--
|
|
2
|
-
# Copyright (c) 2006-
|
|
2
|
+
# Copyright (c) 2006-2016, 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
|
|
@@ -41,7 +41,7 @@ class Rufus::Scheduler
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
#
|
|
44
|
-
# The standard flock
|
|
44
|
+
# The standard flock mechanism, with its own class thanks to @ecin
|
|
45
45
|
#
|
|
46
46
|
class FileLock
|
|
47
47
|
|