rufus-scheduler 3.2.2 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d295240539281a67916e2d17affe1b83406f28ff
4
- data.tar.gz: a597f93ce56ecd1988f65d8fe46a9cd5401974fb
3
+ metadata.gz: f5efdaec8fd127103673241abfcb7a14d9135aef
4
+ data.tar.gz: 95b4b8f72eaea194b946e9b6738fa42b9086fc2a
5
5
  SHA512:
6
- metadata.gz: 39652b4c2cbf22b58b4a216fb866ab292eacb2042a7acc740d5d1c5bd936e3a68a0307cb4bcfc7b463b256751c1dd465bc8b32bc05130d9bce1b11fc16518b16
7
- data.tar.gz: 37f9c3f06c4a49e75e3d38b20cd4a7bd8934263d671a78d78d5daa2c71f68d1a7273653512ca5b5fafc07412fa8a5b4c12c390bb57d9db0072887b8d84e8f7f4
6
+ metadata.gz: d511d09f4a9c0deffd90a97005d0824b891a55a92236cf885fde676830960ebbaad407d1a4fd4817b81d20d0f7ef9a504ad35b96a58b7a195e30bae89eda0046
7
+ data.tar.gz: d4da5209b9d01d6a4c861ed022b36971377762ae31ec785d068c0070af3e098e0ff0f6939cd128a96f5752deb74c49daf798a074d6a7557fa80d125f4286dcd5
@@ -2,6 +2,14 @@
2
2
  = rufus-scheduler CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-scheduler - 3.3.0 released 2016-11-28
6
+
7
+ - Bring in Piavka's Job#trigger_off_schedule, gh-214
8
+ - Reject "day 0" in cronlines, thanks to Ramon Tayag, https://github.com/ramontayag
9
+ - Move away from ENV['TZ'], thanks to Akinori Musha, https://github.com/knu
10
+ - Fix .parse_to_time vs Date issue, as reported by @nsatragno
11
+
12
+
5
13
  == rufus-scheduler - 3.2.2 released 2016-08-14
6
14
 
7
15
  - job opt hash preservation, as suggested in gh-212, by https://github.com/d-m-u
@@ -4,6 +4,7 @@
4
4
 
5
5
  == Contributors
6
6
 
7
+ - Piavka (https://github.com/piavka) - Job#trigger_off_schedule, gh-214
7
8
  - Paulo Delgado (https://github.com/paulodelgado) counter ActiveRecord, gh-210
8
9
  - Anjali Sharma (https://github.com/anjali-sharma) enhance job#last_time example
9
10
  - Kyle Simukka (https://github.com/simook) raise on "*/0 * * * *"
@@ -50,6 +51,9 @@
50
51
 
51
52
  == Feedback
52
53
 
54
+ - Ramon Tayag - https://github.com/ramontayag - prevent day 0 in cronlines
55
+ - Akinori Musha - https://github.com/knu - ENV['TZ'] setting is harmful
56
+ - Nicolás Satragno - https://twitter.com/nsatragno - parse_to_time vs Date
53
57
  - d-m-u duhlmann - https://github.com/d-m-u - job opt hash preservation
54
58
  - Anjali Sharma - https://github.com/anjali-sharma - fix typographical error
55
59
  - Jonathan Campos - https://github.com/jonbcampos - negative cron day idea
data/README.md CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  Job scheduler for Ruby (at, cron, in and every jobs).
8
8
 
9
+ It uses threads.
10
+
9
11
  **Note**: maybe are you looking for the [README of rufus-scheduler 2.x](https://github.com/jmettraux/rufus-scheduler/blob/two/README.rdoc)?
10
12
 
11
13
  Quickstart:
@@ -55,10 +57,12 @@ end
55
57
 
56
58
  ## non-features
57
59
 
58
- Rufus-scheduler (out of the box) is an in-process, in-memory scheduler.
60
+ Rufus-scheduler (out of the box) is an in-process, in-memory scheduler. It uses threads.
59
61
 
60
62
  It does not persist your schedules. When the process is gone and the scheduler instance with it, the schedules are gone.
61
63
 
64
+ A rufus-scheduler instance will go on scheduling while it is present among the object in a Ruby process. To make it stop scheduling you have to call its [`#shutdown` method](#schedulershutdown).
65
+
62
66
 
63
67
  ## related and similar gems
64
68
 
@@ -371,6 +375,8 @@ Since, by default, jobs are triggered in their own new thread, job instances mig
371
375
 
372
376
  To prevent overlap, one can set :overlap => false. Such a job will not trigger if one of its instance is already running.
373
377
 
378
+ The `:overlap` option is considered before the `:mutex` option when the scheduler is reviewing jobs for triggering.
379
+
374
380
  ### :mutex => mutex_instance / mutex_name / array of mutexes
375
381
 
376
382
  When a job with a mutex triggers, the job's block is executed with the mutex around it, preventing other jobs with the same mutex to enter (it makes the other jobs wait until it exits the mutex).
@@ -383,6 +389,8 @@ Array of mutexes: original idea and implementation by [Rainux Luo](https://githu
383
389
 
384
390
  Warning: creating lots of different mutexes is OK. Rufus-scheduler will place them in its Scheduler#mutexes hash... And they won't get garbage collected.
385
391
 
392
+ The `:overlap` option is considered before the `:mutex` option when the scheduler is reviewing jobs for triggering.
393
+
386
394
  ### :timeout => duration or point in time
387
395
 
388
396
  It's OK to specify a timeout when scheduling some work. After the time specified, it gets interrupted via a Rufus::Scheduler::TimeoutError.
@@ -0,0 +1,12 @@
1
+
2
+ rspec ./spec/job_spec.rb:640 # Rufus::Scheduler::Job work time #mean_work_time gathers work times and computes the mean
3
+ rspec ./spec/schedule_at_spec.rb:60 # Rufus::Scheduler#at triggers a job
4
+ rspec ./spec/schedule_in_spec.rb:44 # Rufus::Scheduler#in removes the job after execution
5
+ rspec ./spec/scheduler_spec.rb:83 # Rufus::Scheduler a schedule method passes the job to its block when it triggers
6
+ rspec ./spec/scheduler_spec.rb:534 # Rufus::Scheduler#running_jobs(:tag/:tags => x) returns a list of running jobs filtered by tag
7
+ rspec ./spec/scheduler_spec.rb:601 # Rufus::Scheduler#occurrences(time0, time1) respects :times for repeat jobs
8
+ rspec ./spec/scheduler_spec.rb:1019 # Rufus::Scheduler#on_post_trigger is called right after a job triggers
9
+
10
+
11
+ determine_id specs are slower... much slower...
12
+
@@ -25,7 +25,7 @@
25
25
  require 'date' if RUBY_VERSION < '1.9.0'
26
26
  require 'time'
27
27
  require 'thread'
28
- #require 'tzinfo'
28
+ require 'tzinfo'
29
29
 
30
30
 
31
31
  module Rufus
@@ -39,7 +39,7 @@ module Rufus
39
39
  require 'rufus/scheduler/job_array'
40
40
  require 'rufus/scheduler/locks'
41
41
 
42
- VERSION = '3.2.2'
42
+ VERSION = '3.3.0'
43
43
 
44
44
  #
45
45
  # A common error class for rufus-scheduler
@@ -154,7 +154,7 @@ module Rufus
154
154
 
155
155
  def uptime
156
156
 
157
- @started_at ? Time.now - @started_at : nil
157
+ @started_at ? Rufus::Scheduler::ZoTime.now - @started_at : nil
158
158
  end
159
159
 
160
160
  def uptime_s
@@ -478,6 +478,7 @@ module Rufus
478
478
  stderr.puts(" #{pre} tz:")
479
479
  stderr.puts(" #{pre} ENV['TZ']: #{ENV['TZ']}")
480
480
  stderr.puts(" #{pre} Time.now: #{Time.now}")
481
+ stderr.puts(" #{pre} local_tzone: #{Rufus::Scheduler::ZoTime.local_tzone.inspect}")
481
482
  stderr.puts(" #{pre} scheduler:")
482
483
  stderr.puts(" #{pre} object_id: #{object_id}")
483
484
  stderr.puts(" #{pre} opts:")
@@ -557,7 +558,7 @@ module Rufus
557
558
 
558
559
  def start
559
560
 
560
- @started_at = Time.now
561
+ @started_at = Rufus::Scheduler::ZoTime.now
561
562
 
562
563
  @thread =
563
564
  Thread.new do
@@ -584,7 +585,7 @@ module Rufus
584
585
 
585
586
  def trigger_jobs
586
587
 
587
- now = Time.now
588
+ now = Rufus::Scheduler::ZoTime.now
588
589
 
589
590
  @jobs.each(now) do |job|
590
591
 
@@ -603,9 +604,9 @@ module Rufus
603
604
  next unless job && to && ts
604
605
  # thread might just have become inactive (job -> nil)
605
606
 
606
- to = to.is_a?(Time) ? to : ts + to
607
+ to = ts + to unless to.is_a?(Rufus::Scheduler::ZoTime)
607
608
 
608
- next if to > Time.now
609
+ next if to > Rufus::Scheduler::ZoTime.now
609
610
 
610
611
  t.raise(Rufus::Scheduler::TimeoutError)
611
612
  end
@@ -626,7 +627,7 @@ module Rufus
626
627
  case job_type
627
628
  when :once
628
629
  opts[:_t] ||= Rufus::Scheduler.parse(t, opts)
629
- opts[:_t].is_a?(Time) ? AtJob : InJob
630
+ opts[:_t].is_a?(Numeric) ? InJob : AtJob
630
631
  when :every
631
632
  EveryJob
632
633
  when :interval
@@ -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 = items.pop if ZoTime.is_timezone?(items.last)
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}'"
@@ -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
- time = ZoTime.new(time.to_f, @timezone || ENV['TZ']).time
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?(time, :sec, @seconds)
89
- return false unless sub_match?(time, :min, @minutes)
90
- return false unless sub_match?(time, :hour, @hours)
91
- return false unless date_match?(time)
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=Time.now)
136
+ def next_time(from=ZoTime.now)
123
137
 
124
- time = nil
125
- zotime = ZoTime.new(from.to_i + 1, @timezone || ENV['TZ'])
138
+ nt = nil
139
+ zt = ZoTime.new(from.to_i + 1, @timezone)
126
140
 
127
141
  loop do
128
142
 
129
- time = zotime.time
143
+ nt = zt.dup
130
144
 
131
- unless date_match?(time)
132
- zotime.add((24 - time.hour) * 3600 - time.min * 60 - time.sec)
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?(time, :hour, @hours)
136
- zotime.add((60 - time.min) * 60 - time.sec)
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?(time, :min, @minutes)
140
- zotime.add(60 - time.sec)
153
+ unless sub_match?(nt, :min, @minutes)
154
+ zt.add(60 - nt.sec)
141
155
  next
142
156
  end
143
- unless sub_match?(time, :sec, @seconds)
144
- zotime.add(next_second(time))
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
- time
165
+ nt
152
166
  end
153
167
 
154
168
  # Returns the previous time the cronline matched. It's like next_time, but
@@ -156,34 +170,34 @@ class Rufus::Scheduler
156
170
  #
157
171
  def previous_time(from=Time.now)
158
172
 
159
- time = nil
160
- zotime = ZoTime.new(from.to_i - 1, @timezone || ENV['TZ'])
173
+ pt = nil
174
+ zt = ZoTime.new(from.to_i - 1, @timezone)
161
175
 
162
176
  loop do
163
177
 
164
- time = zotime.time
178
+ pt = zt.dup
165
179
 
166
- unless date_match?(time)
167
- zotime.substract(time.hour * 3600 + time.min * 60 + time.sec + 1)
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?(time, :hour, @hours)
171
- zotime.substract(time.min * 60 + time.sec + 1)
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?(time, :min, @minutes)
175
- zotime.substract(time.sec + 1)
188
+ unless sub_match?(pt, :min, @minutes)
189
+ zt.substract(pt.sec + 1)
176
190
  next
177
191
  end
178
- unless sub_match?(time, :sec, @seconds)
179
- zotime.substract(prev_second(time))
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
- time
200
+ pt
187
201
  end
188
202
 
189
203
  # Returns an array of 6 arrays (seconds, minutes, hours, days,
@@ -200,7 +214,7 @@ 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
206
220
  alias to_array to_a
@@ -260,7 +274,9 @@ class Rufus::Scheduler
260
274
  break if delta <= 1
261
275
  break if delta <= 60 && @seconds && @seconds.size == 1
262
276
 
277
+ #st = Time.now
263
278
  t1 = next_time(t0)
279
+ #p Time.now - st
264
280
  d = t1 - t0
265
281
  delta = d if d < delta
266
282
 
@@ -314,7 +330,6 @@ class Rufus::Scheduler
314
330
 
315
331
  WEEKDAYS = %w[ sun mon tue wed thu fri sat ]
316
332
  DAY_S = 24 * 3600
317
- WEEK_S = 7 * DAY_S
318
333
 
319
334
  def parse_weekdays(item)
320
335
 
@@ -431,12 +446,14 @@ class Rufus::Scheduler
431
446
  r.uniq
432
447
  end
433
448
 
449
+ # FIXME: Eventually split into day_match?, hour_match? and monthdays_match?o
450
+ #
434
451
  def sub_match?(time, accessor, values)
435
452
 
436
- value = time.send(accessor)
437
-
438
453
  return true if values.nil?
439
454
 
455
+ value = time.send(accessor)
456
+
440
457
  if accessor == :day
441
458
 
442
459
  values.each do |v|
@@ -450,48 +467,31 @@ class Rufus::Scheduler
450
467
  return true if value == 0 && values.include?(24)
451
468
  end
452
469
 
453
- values.include?(value)
454
- end
455
-
456
- def monthday_match?(date, values)
470
+ if accessor == :monthdays
457
471
 
458
- return true if values.nil?
459
-
460
- today_values = monthdays(date)
461
-
462
- (today_values & values).any?
463
- end
464
-
465
- def date_match?(date)
472
+ return true if (values & value).any?
473
+ end
466
474
 
467
- return false unless sub_match?(date, :day, @days)
468
- return false unless sub_match?(date, :month, @months)
469
- return false unless sub_match?(date, :wday, @weekdays)
470
- return false unless monthday_match?(date, @monthdays)
471
- true
475
+ values.include?(value)
472
476
  end
473
477
 
474
- def monthdays(date)
475
-
476
- pos = 1
477
- d = date.dup
478
-
479
- loop do
480
- d = d - WEEK_S
481
- break if d.month != date.month
482
- pos = pos + 1
483
- end
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
484
486
 
485
- neg = -1
486
- d = date.dup
487
+ def date_match?(zt)
487
488
 
488
- loop do
489
- d = d + WEEK_S
490
- break if d.month != date.month
491
- neg = neg - 1
492
- end
493
-
494
- [ "#{date.wday}##{pos}", "#{date.wday}##{neg}" ]
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
495
495
  end
496
496
  end
497
497
  end
@@ -53,10 +53,14 @@ module Rufus
53
53
 
54
54
  def each(now, &block)
55
55
 
56
- to_a.sort_by { |j| j.next_time || (now + 1) }.each do |job|
56
+ to_a.sort_by do |job|
57
57
 
58
- break unless job.next_time
59
- break if job.next_time > now
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