rufus-scheduler 1.0.11 → 1.0.12

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -1,6 +1,12 @@
1
1
 
2
2
  = rufus-scheduler CHANGELOG.txt
3
3
 
4
+ == rufus-scheduler - 1.0.12 not yet released
5
+
6
+ - todo #23257 : added :timeout parameter for cron/in/at/every
7
+ - bug #22546 : added note about CronLine#next_time, K Liu
8
+ - todo #22489 : find_jobs(tag=nil) patch by Xianhang Zhang
9
+
4
10
 
5
11
  == rufus-scheduler - 1.0.11 released 2008/09/03
6
12
 
data/CREDITS.txt CHANGED
@@ -3,6 +3,9 @@
3
3
 
4
4
  == Feedback
5
5
 
6
+ - Tim Uckun, :timeout concept
7
+ - K Liu, for the note about CronLine#next_time
8
+ - Xianhang Zhang, find_jobs(tag=nil) patch
6
9
  - Yi Wen, for lib/rufus-scheduler.rb
7
10
  - Adam Green and Rael Dornfest for the Taskr breaking issue feedback
8
11
  - Sean Liu, unschedule_every issue
data/README.txt CHANGED
@@ -44,6 +44,8 @@ some examples :
44
44
  init_self_destruction_sequence()
45
45
  end
46
46
 
47
+ scheduler.join # join the scheduler (prevents exiting)
48
+
47
49
 
48
50
  For all the scheduling related information, see the Rufus::Scheduler class rdoc itself (http://rufus.rubyforge.org/rufus-scheduler/classes/Rufus/Scheduler.html) or the original OpenWFEru scheduler documentation at http://openwferu.rubyforge.org/scheduler.html
49
51
 
@@ -63,6 +65,11 @@ Apart from scheduling, There are also two interesting methods in this gem, they
63
65
  Rufus.to_time_string 7 * 24 * 3600 # => '1w'
64
66
 
65
67
 
68
+ Something about the rufus-scheduler, threads and ActiveRecord connections :
69
+
70
+ http://jmettraux.wordpress.com/2008/09/14/the-scheduler-and-the-active_record/
71
+
72
+
66
73
  == dependencies
67
74
 
68
75
  None.
@@ -123,6 +123,25 @@ module Rufus
123
123
  #
124
124
  # This is raw, 3 secs to iterate over 1 year on my macbook :( brutal.
125
125
  #
126
+ # This method accepts an optional Time parameter. It's the starting point
127
+ # for the 'search'. By default, it's Time.now
128
+ #
129
+ # Note that the time instance returned will be in the same time zone that
130
+ # the given start point Time (thus a result in the local time zone will
131
+ # be passed if no start time is specified (search start time set to
132
+ # Time.now))
133
+ #
134
+ # >> Rufus::CronLine.new('30 7 * * *').next_time( Time.mktime(2008,10,24,7,29) )
135
+ # => Fri Oct 24 07:30:00 -0500 2008
136
+ #
137
+ # >> Rufus::CronLine.new('30 7 * * *').next_time( Time.utc(2008,10,24,7,29) )
138
+ # => Fri Oct 24 07:30:00 UTC 2008
139
+ #
140
+ # >> Rufus::CronLine.new('30 7 * * *').next_time( Time.utc(2008,10,24,7,29) ).localtime
141
+ # => Fri Oct 24 02:30:00 -0500 2008
142
+ #
143
+ # (Thanks to K Liu for the note and the examples)
144
+ #
126
145
  def next_time (now = Time.now)
127
146
 
128
147
  #
@@ -29,7 +29,6 @@
29
29
  #
30
30
 
31
31
  require 'thread'
32
- require 'monitor'
33
32
  require 'rufus/otime'
34
33
  require 'rufus/cronline'
35
34
 
@@ -82,6 +81,9 @@ module Rufus
82
81
  # init_self_destruction_sequence()
83
82
  # end
84
83
  #
84
+ # scheduler.join # join the scheduler (prevents exiting)
85
+ #
86
+ #
85
87
  # an example that uses a Schedulable class :
86
88
  #
87
89
  # class Regenerator < Schedulable
@@ -218,6 +220,13 @@ module Rufus
218
220
  # end
219
221
  # end
220
222
  #
223
+ # # or
224
+ #
225
+ # def scheduler.lwarn (&block)
226
+ # puts "oops, something wrong happened : "
227
+ # puts block.call
228
+ # end
229
+ #
221
230
  # # 2 - overriding the [protected] method log_exception(e) :
222
231
  #
223
232
  # class << scheduler
@@ -226,6 +235,12 @@ module Rufus
226
235
  # end
227
236
  # end
228
237
  #
238
+ # # or
239
+ #
240
+ # def scheduler.log_exception (e)
241
+ # puts "something wrong happened : "+e.to_s
242
+ # end
243
+ #
229
244
  # == 'Every jobs' and rescheduling
230
245
  #
231
246
  # Every jobs can reschedule/unschedule themselves. A reschedule example :
@@ -304,9 +319,25 @@ module Rufus
304
319
  # will return the thread of the last triggered instance, thus, in case
305
320
  # of overlapping executions, you only get the most recent thread.
306
321
  #
322
+ #
323
+ # == specifying a :timeout for a job
324
+ #
325
+ # rufus-scheduler 1.0.12 introduces a :timeout parameter for jobs.
326
+ #
327
+ # scheduler.every "3h", :timeout => '2h30m' do
328
+ # do_that_long_job()
329
+ # end
330
+ #
331
+ # after 2 hours and half, the 'long job' will get interrupted by a
332
+ # Rufus::TimeOutError (so that you know what to catch).
333
+ #
334
+ # :timeout is applicable to all types of jobs : at, in, every, cron. It
335
+ # accepts a String value following the "Mdhms" scheme the rufus-scheduler
336
+ # uses.
337
+ #
307
338
  class Scheduler
308
339
 
309
- VERSION = '1.0.11'
340
+ VERSION = '1.0.12'
310
341
 
311
342
  #
312
343
  # By default, the precision is 0.250, with means the scheduler
@@ -319,7 +350,7 @@ module Rufus
319
350
  #
320
351
  def precision= (f)
321
352
 
322
- raise "precision must be 0.0 < p <= 1.0" \
353
+ raise 'precision must be 0.0 < p <= 1.0' \
323
354
  if f <= 0.0 or f > 1.0
324
355
 
325
356
  @precision = f
@@ -401,7 +432,7 @@ module Rufus
401
432
 
402
433
  next if d > @precision
403
434
 
404
- sleep (@precision - d)
435
+ sleep(@precision - d)
405
436
  end
406
437
  end
407
438
  end
@@ -552,12 +583,14 @@ module Rufus
552
583
  #
553
584
  def schedule_every (freq, params={}, &block)
554
585
 
555
- params = prepare_params params
586
+ params = prepare_params(params)
556
587
  params[:every] = freq
557
588
 
558
589
  first_at = params[:first_at]
559
590
  first_in = params[:first_in]
560
591
 
592
+ #params[:delayed] = true if first_at or first_in
593
+
561
594
  first_at = if first_at
562
595
  at_to_f(first_at)
563
596
  elsif first_in
@@ -679,10 +712,19 @@ module Rufus
679
712
  #
680
713
  # Returns an array of jobs that have the given tag.
681
714
  #
682
- def find_jobs (tag)
715
+ def find_jobs (tag=nil)
683
716
 
684
- @cron_jobs.values.find_all { |job| job.has_tag?(tag) } +
685
- @non_cron_jobs.values.find_all { |job| job.has_tag?(tag) }
717
+ jobs = @cron_jobs.values + @non_cron_jobs.values
718
+ jobs = jobs.select { |job| job.has_tag?(tag) } if tag
719
+ jobs
720
+ end
721
+
722
+ #
723
+ # Returns all the jobs in the scheduler.
724
+ #
725
+ def all_jobs
726
+
727
+ find_jobs()
686
728
  end
687
729
 
688
730
  #
@@ -779,15 +821,15 @@ module Rufus
779
821
  #
780
822
  def do_schedule_at (at, params={}, &block)
781
823
 
782
- job = params.delete :job
824
+ job = params.delete(:job)
783
825
 
784
826
  unless job
785
827
 
786
828
  jobClass = params[:every] ? EveryJob : AtJob
787
829
 
788
- b = to_block params, &block
830
+ b = to_block(params, &block)
789
831
 
790
- job = jobClass.new self, at_to_f(at), params[:job_id], params, &b
832
+ job = jobClass.new(self, at_to_f(at), params[:job_id], params, &b)
791
833
  end
792
834
 
793
835
  if jobClass == AtJob && job.at < (Time.new.to_f + @precision)
@@ -1020,9 +1062,15 @@ module Rufus
1020
1062
  end
1021
1063
  end
1022
1064
 
1065
+ #
1066
+ # This error is thrown when the :timeout attribute triggers
1067
+ #
1068
+ class TimeOutError < RuntimeError
1069
+ end
1070
+
1023
1071
  protected
1024
1072
 
1025
- JOB_ID_LOCK = Monitor.new
1073
+ JOB_ID_LOCK = Mutex.new
1026
1074
  #
1027
1075
  # would it be better to use a Mutex instead of a full-blown
1028
1076
  # Monitor ?
@@ -1131,7 +1179,19 @@ module Rufus
1131
1179
  @trigger_thread = nil
1132
1180
  # overlapping executions, what to do ?
1133
1181
  end
1182
+
1183
+ if trigger_thread_alive? and (to = @params[:timeout])
1184
+ @scheduler.in(to, :tags => 'timeout') do
1185
+ @trigger_thread.raise(Rufus::TimeOutError) if trigger_thread_alive?
1186
+ end
1187
+ end
1134
1188
  end
1189
+
1190
+ protected
1191
+
1192
+ def trigger_thread_alive?
1193
+ (@trigger_thread && @trigger_thread.alive?)
1194
+ end
1135
1195
  end
1136
1196
 
1137
1197
  #
data/test/cron_test.rb CHANGED
@@ -7,9 +7,10 @@
7
7
  # Sun Oct 29 16:18:25 JST 2006
8
8
  #
9
9
 
10
- require 'test/unit'
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
11
 
12
- require 'openwfe/util/scheduler'
12
+ require 'test/unit'
13
+ require 'rufus/scheduler'
13
14
 
14
15
 
15
16
  #
@@ -7,8 +7,9 @@
7
7
  # Sun Oct 29 16:18:25 JST 2006
8
8
  #
9
9
 
10
- require 'test/unit'
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
11
 
12
+ require 'test/unit'
12
13
  require 'rufus/scheduler'
13
14
 
14
15
 
data/test/dev.rb CHANGED
@@ -24,5 +24,5 @@ s.schedule "* * * * *" do
24
24
  puts "#{tcurr.to_s} #{tcurr.to_f} (#{compute_dev(s, tprev, tcurr)})"
25
25
  end
26
26
 
27
- s.join
27
+ s.join
28
28
 
@@ -7,22 +7,17 @@
7
7
  # Sun Oct 29 16:18:25 JST 2006
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
- require 'openwfe/util/scheduler'
13
+ require 'rufus/scheduler'
12
14
 
13
15
 
14
16
  #
15
17
  # testing otime and the scheduler
16
18
  #
17
-
18
19
  class Scheduler0Test < Test::Unit::TestCase
19
20
 
20
- #def setup
21
- #end
22
-
23
- #def teardown
24
- #end
25
-
26
21
  def test_scheduler_0
27
22
 
28
23
  #Thread.abort_on_exception = true
@@ -7,21 +7,17 @@
7
7
  # Sun Oct 29 16:18:25 JST 2006
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'openwfe/util/scheduler'
12
14
 
15
+
13
16
  #
14
17
  # testing otime and the scheduler
15
18
  #
16
-
17
19
  class Scheduler1Test < Test::Unit::TestCase
18
20
 
19
- #def setup
20
- #end
21
-
22
- #def teardown
23
- #end
24
-
25
21
  def test_0
26
22
 
27
23
  scheduler = Rufus::Scheduler.new
@@ -7,21 +7,17 @@
7
7
  # Sun Oct 29 16:18:25 JST 2006
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'openwfe/util/scheduler'
12
14
 
15
+
13
16
  #
14
17
  # testing otime and the scheduler
15
18
  #
16
-
17
19
  class Scheduler2Test < Test::Unit::TestCase
18
20
 
19
- #def setup
20
- #end
21
-
22
- #def teardown
23
- #end
24
-
25
21
  def test_0
26
22
 
27
23
  scheduler = Rufus::Scheduler.new
@@ -7,18 +7,14 @@
7
7
  # Sun Oct 29 16:18:25 JST 2006
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'openwfe/util/scheduler'
12
14
 
13
15
 
14
16
  class Scheduler3Test < Test::Unit::TestCase
15
17
 
16
- #def setup
17
- #end
18
-
19
- #def teardown
20
- #end
21
-
22
18
  #
23
19
  # Testing tags
24
20
  #
@@ -50,6 +46,13 @@ class Scheduler3Test < Test::Unit::TestCase
50
46
  assert_equal 2, scheduler.find_jobs('fish').size
51
47
  #puts scheduler.find_jobs('fish')
52
48
 
49
+ assert_equal(
50
+ 3,
51
+ scheduler.all_jobs.size)
52
+ assert_equal(
53
+ [ "Rufus::CronJob", "Rufus::CronJob", "Rufus::AtJob" ],
54
+ scheduler.all_jobs.collect { |j| j.class.name })
55
+
53
56
  scheduler.find_jobs('fish').each do |job|
54
57
  scheduler.unschedule(job.job_id)
55
58
  end
@@ -7,18 +7,14 @@
7
7
  # Tue Jan 8 13:46:17 JST 2008
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'rufus/scheduler'
12
14
 
13
15
 
14
16
  class Scheduler4Test < Test::Unit::TestCase
15
17
 
16
- #def setup
17
- #end
18
-
19
- #def teardown
20
- #end
21
-
22
18
  #
23
19
  # Checking that a sleep in a schedule won't raise any exception
24
20
  #
@@ -7,18 +7,14 @@
7
7
  # Sat Jan 26 20:05:57 JST 2008
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'rufus/scheduler'
12
14
 
13
15
 
14
16
  class Scheduler5Test < Test::Unit::TestCase
15
17
 
16
- #def setup
17
- #end
18
-
19
- #def teardown
20
- #end
21
-
22
18
  #
23
19
  # Testing the :first_at parameter
24
20
  #
@@ -31,7 +27,7 @@ class Scheduler5Test < Test::Unit::TestCase
31
27
 
32
28
  fa = Time.now + 3
33
29
 
34
- s.schedule_every "1s", :first_at => fa do
30
+ s.schedule_every '1s', :first_at => fa do
35
31
  $count += 1
36
32
  end
37
33
 
@@ -60,7 +56,7 @@ class Scheduler5Test < Test::Unit::TestCase
60
56
 
61
57
  $count = 0
62
58
 
63
- s.schedule_every "1s", :first_in => "3s" do
59
+ s.schedule_every '1s', :first_in => '3s' do
64
60
  $count += 1
65
61
  end
66
62
 
@@ -78,5 +74,79 @@ class Scheduler5Test < Test::Unit::TestCase
78
74
 
79
75
  s.stop
80
76
  end
77
+
78
+ #
79
+ # Testing the :timeout parameter
80
+ #
81
+ def test_2
82
+
83
+ s = Rufus::Scheduler.start_new
84
+
85
+ $count = 0
86
+ $error = nil
87
+
88
+ def s.log_exception (e)
89
+ $error = e
90
+ end
91
+
92
+ s.in '3s', :timeout => '2s' do
93
+ loop do
94
+ $count += 1
95
+ sleep 3
96
+ end
97
+ end
98
+
99
+ sleep 6
100
+
101
+ assert_kind_of Rufus::TimeOutError, $error
102
+ assert_equal 1, $count
103
+
104
+ s.stop
105
+ end
106
+
107
+ #
108
+ # Testing the :first_in + :timeout parameters
109
+ #
110
+ def test_3
111
+
112
+ s = Rufus::Scheduler.start_new
113
+
114
+ $count = 0
115
+ $error = nil
116
+ $jobs = nil
117
+ $status = :out
118
+
119
+ def s.log_exception (e)
120
+ $error = e
121
+ $status = :timedout
122
+ end
123
+
124
+ s.every '5s', :first_in => '2s', :timeout => '1s' do
125
+ $status = :in
126
+ Thread.pass # let the timeout job get scheduled
127
+ jobs = s.all_jobs
128
+ $jobs = [ jobs.size, jobs.collect { |j| j.tags }.flatten ]
129
+ $count += 1
130
+ sleep 4
131
+ $status = :out
132
+ end
133
+
134
+ sleep 4 # until after 1st timeout
135
+
136
+ assert_kind_of Rufus::TimeOutError, $error
137
+ assert_equal 1, $count
138
+ assert_equal [ 2, [ 'timeout' ] ], $jobs
139
+ assert_equal :timedout, $status
140
+
141
+ assert_equal 1, s.all_jobs.size
142
+
143
+ sleep 3.5 # right in the middle of the 2nd timeout
144
+
145
+ assert_equal :in, $status
146
+ assert_equal 2, s.all_jobs.size
147
+ assert_equal [ 'timeout' ], s.all_jobs.collect { |j| j.tags }.flatten
148
+
149
+ s.stop
150
+ end
81
151
  end
82
152
 
@@ -7,18 +7,14 @@
7
7
  # Thu Feb 14 08:19:10 JST 2008
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'rufus/scheduler'
12
14
 
13
15
 
14
16
  class Scheduler6Test < Test::Unit::TestCase
15
17
 
16
- #def setup
17
- #end
18
-
19
- #def teardown
20
- #end
21
-
22
18
  #
23
19
  # just a small test
24
20
  #
@@ -7,6 +7,8 @@
7
7
  # Sun Jul 13 19:20:27 JST 2008
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'rufus/scheduler'
12
14
 
@@ -14,15 +16,8 @@ require 'rufus/scheduler'
14
16
  #
15
17
  # checking if bug #20893 got fixed
16
18
  #
17
-
18
19
  class Scheduler7Test < Test::Unit::TestCase
19
20
 
20
- #def setup
21
- #end
22
-
23
- #def teardown
24
- #end
25
-
26
21
  def test_0
27
22
 
28
23
  count = 0
@@ -7,6 +7,8 @@
7
7
  # Fri Apr 18 11:29:18 JST 2008
8
8
  #
9
9
 
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
+
10
12
  require 'test/unit'
11
13
  require 'openwfe/util/scheduler'
12
14
 
@@ -14,15 +16,8 @@ require 'openwfe/util/scheduler'
14
16
  #
15
17
  # testing otime and the scheduler
16
18
  #
17
-
18
19
  class SchedulerNameTest < Test::Unit::TestCase
19
20
 
20
- #def setup
21
- #end
22
-
23
- #def teardown
24
- #end
25
-
26
21
  def test_0
27
22
 
28
23
  scheduler = Rufus::Scheduler.new
data/test/time_0_test.rb CHANGED
@@ -7,22 +7,17 @@
7
7
  # Sun Oct 29 16:18:25 JST 2006
8
8
  #
9
9
 
10
- require 'test/unit'
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
11
 
12
+ require 'test/unit'
12
13
  require 'rufus/otime'
13
14
 
15
+
14
16
  #
15
17
  # testing otime
16
18
  #
17
-
18
19
  class Time0Test < Test::Unit::TestCase
19
20
 
20
- #def setup
21
- #end
22
-
23
- #def teardown
24
- #end
25
-
26
21
  def _test_to_iso_date
27
22
  #
28
23
  # well... this test is not timezone friendly...
data/test/time_1_test.rb CHANGED
@@ -7,22 +7,17 @@
7
7
  # Fri Feb 29 11:18:48 JST 2008
8
8
  #
9
9
 
10
- require 'test/unit'
10
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
11
11
 
12
+ require 'test/unit'
12
13
  require 'rufus/otime'
13
14
 
15
+
14
16
  #
15
17
  # testing otime
16
18
  #
17
-
18
19
  class Time1Test < Test::Unit::TestCase
19
20
 
20
- #def setup
21
- #end
22
-
23
- #def teardown
24
- #end
25
-
26
21
  def test_0
27
22
 
28
23
  tts 0, "0s"
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.11
4
+ version: 1.0.12
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: 2008-09-03 00:00:00 +09:00
12
+ date: 2008-12-18 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -72,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
72
  requirements: []
73
73
 
74
74
  rubyforge_project:
75
- rubygems_version: 1.2.0
75
+ rubygems_version: 1.3.1
76
76
  signing_key:
77
77
  specification_version: 2
78
78
  summary: scheduler for Ruby (at, cron and every jobs), formerly known as 'openwferu-scheduler'