rufus-scheduler 3.1.3 → 3.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -2,6 +2,11 @@
2
2
  = rufus-scheduler CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-scheduler - 3.1.4 released 2015/08/29
6
+
7
+ - fix cron issue reported by Jesse https://github.com/jhw-at-prosperworks-com
8
+
9
+
5
10
  == rufus-scheduler - 3.1.3 released 2015/06/20
6
11
 
7
12
  - prevent Thread[:rufus_scheduler_time] -> nil, gh-156
data/CREDITS.txt CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  == Contributors
6
6
 
7
+ - Jesse Willet (https://github.com/jhw-at-prosperworks-com) cron vs "*/10"
7
8
  - Pascal Ouellet (https://github.com/pouellet) Scheduler#timeline loop fix
8
9
  - Ryan Biesemeyer (https://github.com/yaauie) ZoTime.is_timezone? on OSX
9
10
  - Ketan Padegaonkar (https://github.com/ketan) .brute_frequency improvement
@@ -39,7 +39,7 @@ module Rufus
39
39
  require 'rufus/scheduler/job_array'
40
40
  require 'rufus/scheduler/locks'
41
41
 
42
- VERSION = '3.1.3'
42
+ VERSION = '3.1.4'
43
43
 
44
44
  #
45
45
  # A common error class for rufus-scheduler
@@ -186,19 +186,6 @@ class Rufus::Scheduler
186
186
  time
187
187
  end
188
188
 
189
- if RUBY_VERSION >= '1.9'
190
- def toa(item)
191
- item == nil ? nil : item.to_a
192
- end
193
- else
194
- def toi(item); item.is_a?(String) ? item.hash.abs : item.to_i; end
195
- protected :toi
196
- def toa(item)
197
- item.is_a?(Set) ? item.to_a.sort_by { |e| toi(e) } : item
198
- end
199
- end
200
- protected :toa
201
-
202
189
  # Returns an array of 6 arrays (seconds, minutes, hours, days,
203
190
  # months, weekdays).
204
191
  # This method is used by the cronline unit tests.
@@ -228,16 +215,12 @@ class Rufus::Scheduler
228
215
 
229
216
  return brute_frequency unless @seconds && @seconds.length > 1
230
217
 
231
- delta = 60
232
218
  secs = toa(@seconds)
233
- prev = secs[0]
234
219
 
235
- secs[1..-1].each do |sec|
220
+ secs[1..-1].inject([ secs[0], 60 ]) { |(prev, delta), sec|
236
221
  d = sec - prev
237
- delta = d if d < delta
238
- end
239
-
240
- delta
222
+ [ sec, d < delta ? d : delta ]
223
+ }[1]
241
224
  end
242
225
 
243
226
  # Returns the shortest delta between two potential occurences of the
@@ -288,13 +271,11 @@ class Rufus::Scheduler
288
271
  delta
289
272
  end
290
273
 
291
- protected
292
-
293
274
  def next_second(time)
294
275
 
295
- secs = @seconds.sort
276
+ secs = toa(@seconds)
296
277
 
297
- return secs.last + 60 - time.sec if time.sec > secs.last
278
+ return secs.first + 60 - time.sec if time.sec > secs.last
298
279
 
299
280
  secs.shift while secs.first < time.sec
300
281
 
@@ -303,13 +284,30 @@ class Rufus::Scheduler
303
284
 
304
285
  def prev_second(time)
305
286
 
306
- secs = @seconds.sort
287
+ secs = toa(@seconds)
307
288
 
308
289
  secs.pop while time.sec < secs.last
309
290
 
310
291
  time.sec - secs.last
311
292
  end
312
293
 
294
+ protected
295
+
296
+ def sc_sort(a)
297
+
298
+ a.sort_by { |e| e.is_a?(String) ? 61 : e.to_i }
299
+ end
300
+
301
+ if RUBY_VERSION >= '1.9'
302
+ def toa(item)
303
+ item == nil ? nil : item.to_a
304
+ end
305
+ else
306
+ def toa(item)
307
+ item.is_a?(Set) ? sc_sort(item.to_a) : item
308
+ end
309
+ end
310
+
313
311
  WEEKDAYS = %w[ sun mon tue wed thu fri sat ]
314
312
  DAY_S = 24 * 3600
315
313
  WEEK_S = 7 * DAY_S
@@ -351,7 +349,7 @@ class Rufus::Scheduler
351
349
  end
352
350
  end
353
351
 
354
- weekdays = weekdays.uniq if weekdays
352
+ weekdays = weekdays.uniq.sort if weekdays
355
353
 
356
354
  [ weekdays, monthdays ]
357
355
  end
@@ -366,6 +364,8 @@ class Rufus::Scheduler
366
364
  "found duplicates in #{item.inspect}"
367
365
  ) if r.uniq.size < r.size
368
366
 
367
+ r = sc_sort(r)
368
+
369
369
  Set.new(r)
370
370
  end
371
371
 
@@ -32,6 +32,10 @@ describe Rufus::Scheduler::CronLine do
32
32
  in_zone(tz) { tu.getlocal }
33
33
  end
34
34
 
35
+ def ns(cronline, now)
36
+ Rufus::Scheduler::CronLine.new(cronline).next_second(now)
37
+ end
38
+
35
39
  def match(line, time)
36
40
  expect(cl(line).matches?(time)).to eq(true)
37
41
  end
@@ -68,20 +72,30 @@ describe Rufus::Scheduler::CronLine do
68
72
 
69
73
  to_a '52 0 * * *', [ [0], [52], [0], nil, nil, nil, nil, nil ]
70
74
 
71
- if ruby18?
72
- to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
73
- else
74
- to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
75
- end
75
+ #if ruby18?
76
+ # to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
77
+ #else
78
+ # to_a '0 23-24 * * *', [ [0], [0], [23, 0], nil, nil, nil, nil, nil ]
79
+ #end
76
80
  #
77
81
  # as reported by Aimee Rose in
78
82
  # https://github.com/jmettraux/rufus-scheduler/issues/56
83
+ to_a '0 23-24 * * *', [ [0], [0], [0, 23], nil, nil, nil, nil, nil ]
79
84
 
80
- if ruby18?
81
- to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
82
- else
83
- to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
84
- end
85
+ #if ruby18?
86
+ # to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
87
+ #else
88
+ # to_a '0 23-2 * * *', [ [0], [0], [23, 0, 1, 2], nil, nil, nil, nil, nil ]
89
+ #end
90
+ to_a '0 23-2 * * *', [ [0], [0], [0, 1, 2, 23], nil, nil, nil, nil, nil ]
91
+
92
+ # modulo forms work for five-field forms
93
+ to_a '*/17 * * * *', [[0], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil]
94
+ to_a '13 */17 * * *', [[0], [13], [0, 17], nil, nil, nil, nil, nil]
95
+
96
+ # modulo forms work for six-field forms
97
+ to_a '*/17 * * * * *', [[0, 17, 34, 51], nil, nil, nil, nil, nil, nil, nil]
98
+ to_a '13 */17 * * * *', [[13], [0, 17, 34, 51], nil, nil, nil, nil, nil, nil]
85
99
  end
86
100
 
87
101
  it 'rejects invalid weekday expressions' do
@@ -215,6 +229,36 @@ describe Rufus::Scheduler::CronLine do
215
229
  # as reported by Aimee Rose in
216
230
  # https://github.com/jmettraux/rufus-scheduler/pull/58
217
231
  end
232
+
233
+ it 'sorts seconds' do
234
+
235
+ to_a(
236
+ '23,30,10 * * * * *', [ [10,23,30], nil, nil, nil, nil, nil, nil, nil ])
237
+ end
238
+
239
+ it 'sorts minutes' do
240
+
241
+ to_a(
242
+ '23,30,10 * * * * ', [ [0], [10,23,30], nil, nil, nil, nil, nil, nil ])
243
+ end
244
+
245
+ it 'sorts days' do
246
+
247
+ to_a(
248
+ '* * 14,7 * * ', [ [0], nil, nil, [7, 14], nil, nil, nil, nil ])
249
+ end
250
+
251
+ it 'sorts months' do
252
+
253
+ to_a(
254
+ '* * * 11,3,4 * ', [ [0], nil, nil, nil, [3,4,11], nil, nil, nil ])
255
+ end
256
+
257
+ it 'sorts days of week' do
258
+
259
+ to_a(
260
+ '* * * * Sun,Fri,2 ', [ [0], nil, nil, nil, nil, [0, 2, 5], nil, nil ])
261
+ end
218
262
  end
219
263
 
220
264
  describe '#next_time' do
@@ -363,6 +407,55 @@ describe Rufus::Scheduler::CronLine do
363
407
  )
364
408
  ).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
365
409
  end
410
+
411
+ it 'understands six-field crontabs' do
412
+
413
+ expect(nt('* * * * * *',local(1970,1,1,1,1,1))).to(
414
+ eq(local(1970,1,1,1,1,2))
415
+ )
416
+ expect(nt('* * * * * *',local(1970,1,1,1,1,2))).to(
417
+ eq(local(1970,1,1,1,1,3))
418
+ )
419
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,0))).to(
420
+ eq(local(1970,1,1,1,1,10))
421
+ )
422
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,9))).to(
423
+ eq(local(1970,1,1,1,1,10))
424
+ )
425
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,10))).to(
426
+ eq(local(1970,1,1,1,1,20))
427
+ )
428
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,40))).to(
429
+ eq(local(1970,1,1,1,1,50))
430
+ )
431
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,49))).to(
432
+ eq(local(1970,1,1,1,1,50))
433
+ )
434
+ expect(nt('*/10 * * * * *',local(1970,1,1,1,1,50))).to(
435
+ eq(local(1970,1,1,1,2,00)) # FAILS: skips a minute to 2:50, not 2:00
436
+ )
437
+ end
438
+ end
439
+
440
+ describe '#next_second' do
441
+ [
442
+ [ '*/10 * * * * *', local(1970,1,1,1,1, 0), 0 ], # 0 sec to 0s mark
443
+ [ '*/10 * * * * *', local(1970,1,1,1,1, 1), 9 ], # 9 sec to 10s mark
444
+ [ '*/10 * * * * *', local(1970,1,1,1,1, 9), 1 ], # 1 sec to 10s mark
445
+ [ '*/10 * * * * *', local(1970,1,1,1,1,10), 0 ], # 0 sec to 10s mark
446
+ [ '*/10 * * * * *', local(1970,1,1,1,1,11), 9 ], # 9 sec to 20s mark
447
+ [ '*/10 * * * * *', local(1970,1,1,1,1,19), 1 ], # 1 sec to 20s mark
448
+ [ '*/10 * * * * *', local(1970,1,1,1,1,20), 0 ], # 0 sec to 20s mark
449
+ [ '*/10 * * * * *', local(1970,1,1,1,1,21), 9 ], # 1 sec to 30s mark
450
+ # ...
451
+ [ '*/10 * * * * *', local(1970,1,1,1,1,49), 1 ], # 9 sec to 50s mark
452
+ [ '*/10 * * * * *', local(1970,1,1,1,1,50), 0 ], # 0 sec to 50s mark
453
+ [ '*/10 * * * * *', local(1970,1,1,1,1,51), 9 ], # FAILS: gives 59
454
+ ].each do |cronline,now,sec|
455
+ it "understands that next_second('#{cronline}',#{now}) is #{sec}" do
456
+ expect(ns(cronline,now)).to eq(sec)
457
+ end
458
+ end
366
459
  end
367
460
 
368
461
  describe '#previous_time' do
@@ -417,6 +510,20 @@ describe Rufus::Scheduler::CronLine do
417
510
  )
418
511
  ).to eq(ltz('America/New_York', 2015, 3, 9, 2, 0, 0))
419
512
  end
513
+
514
+ it 'computes correctly when * 0,10,20' do
515
+
516
+ expect(
517
+ pt('* 0,10,20 * * *', lo(2000, 1, 1))).to eq(
518
+ lo(1999, 12, 31, 20, 59, 00))
519
+ end
520
+
521
+ it 'computes correctly when * */10' do
522
+
523
+ expect(
524
+ pt('* */10 * * *', lo(2000, 1, 1))).to eq(
525
+ lo(1999, 12, 31, 20, 59, 00))
526
+ end
420
527
  end
421
528
 
422
529
  describe '#matches?' do
@@ -543,6 +650,46 @@ describe Rufus::Scheduler::CronLine do
543
650
  expect(Rufus::Scheduler::CronLine.new(
544
651
  '10,20,30 * * * * *').frequency).to eq(10)
545
652
  end
653
+
654
+ it 'spots B-A vs C-B asymmetry in five-field forms' do
655
+
656
+ expect(Rufus::Scheduler::CronLine.new(
657
+ '10,17,30 * * * *').frequency).to eq(7 * 60)
658
+ expect(Rufus::Scheduler::CronLine.new(
659
+ '10,23,30 * * * *').frequency).to eq(7 * 60)
660
+ expect(Rufus::Scheduler::CronLine.new(
661
+ '23,10,30 * * * *').frequency).to eq(7 * 60)
662
+ end
663
+
664
+ it 'spots B-A vs C-B asymmetry in six-field forms' do
665
+
666
+ expect(Rufus::Scheduler::CronLine.new(
667
+ '10,17,30 * * * * *').frequency).to eq(7)
668
+ expect(Rufus::Scheduler::CronLine.new(
669
+ '10,23,30 * * * * *').frequency).to eq(7)
670
+ expect(Rufus::Scheduler::CronLine.new(
671
+ '23,10,30 * * * * *').frequency).to eq(7)
672
+ end
673
+
674
+ it 'handles crontab steps syntax in five-field forms' do
675
+
676
+ expect(Rufus::Scheduler::CronLine.new(
677
+ '*/10 * * * *').frequency).to eq(10 * 60)
678
+ expect(Rufus::Scheduler::CronLine.new(
679
+ '* */10 * * *').frequency).to eq(60) # "*" all minutes [0..59]
680
+ expect(Rufus::Scheduler::CronLine.new(
681
+ '0 */10 * * *').frequency).to eq(4 * 60 * 60) # 2000 to 0000
682
+ end
683
+
684
+ it 'handles crontab steps syntax in six-field forms' do
685
+
686
+ expect(Rufus::Scheduler::CronLine.new(
687
+ '*/10 * * * * *').frequency).to eq(10)
688
+ expect(Rufus::Scheduler::CronLine.new(
689
+ '* */10 * * * *').frequency).to eq(1) # "*" all seconds [0..59]
690
+ expect(Rufus::Scheduler::CronLine.new(
691
+ '0 */10 * * * *').frequency).to eq(10 * 60)
692
+ end
546
693
  end
547
694
 
548
695
  describe '#brute_frequency' do
@@ -574,6 +721,42 @@ describe Rufus::Scheduler::CronLine do
574
721
  expect(Rufus::Scheduler::CronLine.new(
575
722
  '1 2 3 4 5').brute_frequency).to eq(31622400)
576
723
  end
724
+
725
+ it 'spots B-A vs C-B asymmetry in five-field forms' do
726
+
727
+ expect(Rufus::Scheduler::CronLine.new(
728
+ '10,17,30 * * * *').brute_frequency).to eq(7 * 60)
729
+ expect(Rufus::Scheduler::CronLine.new(
730
+ '10,23,30 * * * *').brute_frequency).to eq(7 * 60)
731
+ end
732
+
733
+ it 'spots B-A vs C-B asymmetry in six-field forms' do
734
+
735
+ expect(Rufus::Scheduler::CronLine.new(
736
+ '10,17,30 * * * * *').brute_frequency).to eq(7)
737
+ expect(Rufus::Scheduler::CronLine.new(
738
+ '10,23,30 * * * * *').brute_frequency).to eq(7)
739
+ end
740
+
741
+ it 'handles crontab modulo syntax in five-field forms' do
742
+
743
+ expect(Rufus::Scheduler::CronLine.new(
744
+ '*/10 * * * *').brute_frequency).to eq(10 * 60)
745
+ expect(Rufus::Scheduler::CronLine.new(
746
+ '* */10 * * *').brute_frequency).to eq(60) # "*" all minutes [0..59]
747
+ expect(Rufus::Scheduler::CronLine.new(
748
+ '0 */10 * * *').brute_frequency).to eq(4 * 60 * 60) # 2000 to 0000
749
+ end
750
+
751
+ it 'handles crontab modulo syntax in six-field forms' do
752
+
753
+ expect(Rufus::Scheduler::CronLine.new(
754
+ '*/10 * * * * *').brute_frequency).to eq(10)
755
+ expect(Rufus::Scheduler::CronLine.new(
756
+ '* */10 * * * *').brute_frequency).to eq(1) # "*" all seconds [0..59]
757
+ expect(Rufus::Scheduler::CronLine.new(
758
+ '0 */10 * * * *').brute_frequency).to eq(10 * 60)
759
+ end
577
760
  end
578
761
 
579
762
  context 'summer time' 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: 3.1.3
4
+ version: 3.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-06-19 00:00:00.000000000 Z
12
+ date: 2015-08-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake