rufus-scheduler 2.0.24 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/CHANGELOG.txt +6 -0
  2. data/CREDITS.txt +4 -0
  3. data/README.md +1064 -0
  4. data/Rakefile +1 -4
  5. data/TODO.txt +145 -55
  6. data/lib/rufus/scheduler.rb +502 -26
  7. data/lib/rufus/{sc → scheduler}/cronline.rb +46 -17
  8. data/lib/rufus/{sc/version.rb → scheduler/job_array.rb} +56 -4
  9. data/lib/rufus/scheduler/jobs.rb +548 -0
  10. data/lib/rufus/scheduler/util.rb +318 -0
  11. data/rufus-scheduler.gemspec +30 -4
  12. data/spec/cronline_spec.rb +29 -8
  13. data/spec/error_spec.rb +116 -0
  14. data/spec/job_array_spec.rb +39 -0
  15. data/spec/job_at_spec.rb +58 -0
  16. data/spec/job_cron_spec.rb +67 -0
  17. data/spec/job_every_spec.rb +71 -0
  18. data/spec/job_in_spec.rb +20 -0
  19. data/spec/job_interval_spec.rb +68 -0
  20. data/spec/job_repeat_spec.rb +308 -0
  21. data/spec/job_spec.rb +387 -115
  22. data/spec/lockfile_spec.rb +61 -0
  23. data/spec/parse_spec.rb +203 -0
  24. data/spec/schedule_at_spec.rb +129 -0
  25. data/spec/schedule_cron_spec.rb +66 -0
  26. data/spec/schedule_every_spec.rb +109 -0
  27. data/spec/schedule_in_spec.rb +80 -0
  28. data/spec/schedule_interval_spec.rb +128 -0
  29. data/spec/scheduler_spec.rb +831 -124
  30. data/spec/spec_helper.rb +65 -0
  31. data/spec/threads_spec.rb +75 -0
  32. metadata +64 -59
  33. data/README.rdoc +0 -661
  34. data/lib/rufus/otime.rb +0 -3
  35. data/lib/rufus/sc/jobqueues.rb +0 -160
  36. data/lib/rufus/sc/jobs.rb +0 -471
  37. data/lib/rufus/sc/rtime.rb +0 -363
  38. data/lib/rufus/sc/scheduler.rb +0 -636
  39. data/spec/at_in_spec.rb +0 -47
  40. data/spec/at_spec.rb +0 -125
  41. data/spec/blocking_spec.rb +0 -64
  42. data/spec/cron_spec.rb +0 -134
  43. data/spec/every_spec.rb +0 -304
  44. data/spec/exception_spec.rb +0 -113
  45. data/spec/in_spec.rb +0 -150
  46. data/spec/mutex_spec.rb +0 -159
  47. data/spec/rtime_spec.rb +0 -137
  48. data/spec/schedulable_spec.rb +0 -97
  49. data/spec/spec_base.rb +0 -87
  50. data/spec/stress_schedule_unschedule_spec.rb +0 -159
  51. data/spec/timeout_spec.rb +0 -148
  52. data/test/kjw.rb +0 -113
  53. data/test/t.rb +0 -20
@@ -1,97 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Tue May 5 14:47:16 JST 2009
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe Rufus::Scheduler::Schedulable do
12
-
13
- before(:each) do
14
- @s = start_scheduler
15
- end
16
- after(:each) do
17
- stop_scheduler(@s)
18
- end
19
-
20
- class JobAlpha
21
- attr_reader :value
22
- def trigger(params)
23
- @value = params
24
- end
25
- end
26
- class JobBravo
27
- attr_reader :value
28
- def call(job)
29
- @value = job
30
- end
31
- end
32
-
33
- it 'schedules via :schedulable' do
34
-
35
- j = JobAlpha.new
36
-
37
- @s.in '1s', :schedulable => j
38
-
39
- sleep 1.4
40
-
41
- j.value.class.should == Hash
42
- j.value[:job].class.should == Rufus::Scheduler::InJob
43
- end
44
-
45
- it 'honours schedulables that reply to :call' do
46
-
47
- j = JobBravo.new
48
-
49
- @s.in '1s', :schedulable => j
50
-
51
- sleep 1.4
52
-
53
- j.value.class.should == Rufus::Scheduler::InJob
54
- end
55
-
56
- it 'accepts trigger schedulables as second param' do
57
-
58
- j = JobAlpha.new
59
-
60
- @s.in '1s', j
61
-
62
- sleep 1.4
63
-
64
- j.value.class.should == Hash
65
- j.value[:job].class.should == Rufus::Scheduler::InJob
66
- end
67
-
68
- it 'accepts call schedulables as second param' do
69
-
70
- j = JobBravo.new
71
-
72
- @s.in '1s', j
73
-
74
- sleep 1.4
75
-
76
- j.value.class.should == Rufus::Scheduler::InJob
77
- end
78
-
79
- class MySchedulable
80
- def self.job
81
- @@job
82
- end
83
- def self.call(job)
84
- @@job = job
85
- end
86
- end
87
-
88
- it 'accepts schedulable classes as second param' do
89
-
90
- @s.in '1s', MySchedulable
91
-
92
- sleep 1.4
93
-
94
- MySchedulable.job.class.should == Rufus::Scheduler::InJob
95
- end
96
- end
97
-
data/spec/spec_base.rb DELETED
@@ -1,87 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Fri Mar 20 22:53:33 JST 2009
6
- #
7
-
8
- $:.unshift(File.expand_path('../../lib', __FILE__))
9
-
10
- require 'rubygems'
11
- require 'fileutils'
12
-
13
-
14
- Thread.abort_on_exception = true
15
-
16
-
17
- #$:.unshift(File.expand_path('~/tmp/bacon/lib')) # my own bacon for a while
18
- #require 'bacon'
19
- #puts
20
- #Bacon.summary_on_exit
21
-
22
-
23
- #
24
- # rufus/scheduler/em
25
-
26
- # EM or plain ?
27
-
28
- $plain = ! ENV['EVENTMACHINE']
29
-
30
- require 'rufus/scheduler'
31
-
32
- if ( ! $plain)
33
-
34
- require 'eventmachine'
35
-
36
- unless (EM.reactor_running?)
37
-
38
- Thread.new { EM.run { } }
39
-
40
- sleep 0.200
41
- while (not EM.reactor_running?)
42
- Thread.pass
43
- end
44
- #
45
- # all this waiting, especially for the JRuby eventmachine, which seems
46
- # rather 'diesel'
47
-
48
- end
49
- end
50
-
51
- SCHEDULER_CLASS = $plain ?
52
- Rufus::Scheduler::PlainScheduler :
53
- Rufus::Scheduler::EmScheduler
54
-
55
- #
56
- # helper methods
57
-
58
- def start_scheduler(opts={})
59
- SCHEDULER_CLASS.start_new(opts)
60
- end
61
-
62
- def stop_scheduler(s)
63
- #s.stop(:stop_em => true)
64
- #sleep 0.200 # give time to the EM to stop
65
- s.stop
66
- sleep 0.200
67
- end
68
-
69
- def wait_next_tick
70
- #if defined?(EM)
71
- # t = Thread.current
72
- # EM.next_tick { t.wakeup }
73
- # Thread.stop
74
- #else
75
- sleep 0.500
76
- #end
77
- end
78
-
79
- def local(*args)
80
- Time.local(*args)
81
- end
82
- alias lo local
83
-
84
- def utc(*args)
85
- Time.utc(*args)
86
- end
87
-
@@ -1,159 +0,0 @@
1
-
2
- #
3
- # a spec by Klaas Jan Wierenga
4
- #
5
-
6
- require 'spec_base'
7
-
8
-
9
-
10
- JOB_COUNT = 500 # 1000
11
- JOB_IDS = (1..JOB_COUNT).to_a
12
- NUM_RESCHEDULES = 5 # 10
13
- TRIGGER_DELAY = 4 # 15
14
-
15
-
16
- describe SCHEDULER_CLASS do
17
-
18
- # helper methods
19
-
20
- # Wait for a variable to become a certain value.
21
- # This method returns a block which loops waiting for the passed in
22
- # block paramter to have value 'target'.
23
- #
24
- def eventually(timeout = TRIGGER_DELAY * 2, precision = 1)
25
- lambda { |target|
26
- value = nil
27
- (timeout/precision).to_i.times do
28
- value = yield # read variable once
29
- # puts "got #{value}, expected #{target}"
30
- break if target == value
31
- sleep precision
32
- end
33
- target == value
34
- }
35
- end
36
-
37
- def benchmark
38
- now = Time.now
39
- yield
40
- benchmark = Time.now - now
41
- print " (scheduling took #{benchmark}s)"
42
- if benchmark > TRIGGER_DELAY
43
- puts "\nTEST RESULT INVALID/UNRELIABLE"
44
- puts "Scheduling took longer than TRIGGER_DELAY (#{TRIGGER_DELAY}s)."
45
- puts "Increase TRIGGER_DELAY to a value larger than largest scheduling time."
46
- end
47
- end
48
-
49
- def schedule_unschedule_same_ids_spec(mode)
50
- scheduler = SCHEDULER_CLASS.start_new
51
- benchmark { schedule_unschedule(scheduler, mode, NUM_RESCHEDULES) }
52
- JOB_COUNT.should satisfy &eventually { scheduler.all_jobs.size }
53
- JOB_IDS.sort.should == scheduler.find_jobs.map{ |job| job.job_id }.sort
54
- JOB_COUNT.should satisfy &eventually { @trigger_queue.size }
55
- @trigger_queue.size.should == JOB_COUNT
56
- scheduler.stop
57
- end
58
-
59
- def schedule_unschedule_unique_ids_spec(mode)
60
- scheduler = SCHEDULER_CLASS.start_new
61
- job_ids = []
62
- benchmark { job_ids = schedule_unschedule(scheduler, mode, NUM_RESCHEDULES, true) }
63
- JOB_COUNT.should satisfy &eventually { scheduler.all_jobs.size }
64
- job_ids.sort.should == scheduler.find_jobs.map{ |job| job.job_id }.sort
65
- JOB_COUNT.should satisfy &eventually { @trigger_queue.size }
66
- @trigger_queue.size.should == JOB_COUNT
67
- scheduler.stop
68
- end
69
-
70
- def scheduler_counts(scheduler)
71
- "all:%d at:%d cron:%d every:%d pending:%d" % [
72
- scheduler.all_jobs.size,
73
- scheduler.at_job_count,
74
- scheduler.cron_job_count,
75
- scheduler.every_job_count,
76
- scheduler.pending_job_count ]
77
- end
78
-
79
- def schedule_unschedule(scheduler, mode, num_reschedules, generate_ids=false)
80
- job_ids = schedule_jobs(scheduler, mode, generate_ids)
81
- 1.upto(num_reschedules) do
82
- unschedule_jobs(scheduler, job_ids)
83
- job_ids = schedule_jobs(scheduler, mode, generate_ids)
84
- end
85
- job_ids
86
- end
87
-
88
- def schedule_jobs(scheduler, mode, generate_ids=false)
89
- job_ids = []
90
- JOB_IDS.each do |job_id|
91
- case mode
92
- when :cron
93
- job_ids << scheduler.cron(
94
- "%d * * * * *" % @cron_trigger,
95
- { :job_id => (generate_ids ? nil : job_id) },
96
- &@trigger_proc
97
- ).job_id
98
- when :at
99
- job_ids << scheduler.at(
100
- @at_trigger,
101
- { :job_id => (generate_ids ? nil : job_id) },
102
- &@trigger_proc
103
- ).job_id
104
- when :every
105
- job_ids << scheduler.every(
106
- @every_trigger,
107
- { :job_id => (generate_ids ? nil : job_id) },
108
- &@trigger_proc
109
- ).job_id
110
- else
111
- raise ArgumentError
112
- end
113
- end
114
- job_ids
115
- end
116
-
117
- def unschedule_jobs(scheduler, job_ids)
118
- job_ids.each { |job_id| scheduler.unschedule(job_id) }
119
- end
120
-
121
- # the actual tests
122
-
123
- before(:each) do
124
- @trigger_queue = Queue.new
125
- @cron_trigger = ((Time.now.to_i%60) + TRIGGER_DELAY) % 60 # 30 seconds from now
126
- @at_trigger = Time.now + TRIGGER_DELAY
127
- @every_trigger = "#{TRIGGER_DELAY}s"
128
- @trigger_proc = lambda { |job| @trigger_queue << job.job_id }
129
- end
130
-
131
- after(:each) do
132
- @trigger_queue = nil
133
- end
134
-
135
- it "sustains frequent schedule/unschedule 'cron' jobs with same ids" do
136
- schedule_unschedule_same_ids_spec(:cron)
137
- end
138
-
139
- it "sustains frequent schedule/unschedule 'at' jobs with same ids" do
140
- schedule_unschedule_same_ids_spec(:at)
141
- end
142
-
143
- it "sustains frequent schedule/unschedule 'every' jobs same ids" do
144
- schedule_unschedule_same_ids_spec(:every)
145
- end
146
-
147
- it "sustains frequent schedule/unschedule 'cron' jobs with unique ids" do
148
- schedule_unschedule_unique_ids_spec(:cron)
149
- end
150
-
151
- it "sustains frequent schedule/unschedule 'at' jobs with unique ids" do
152
- schedule_unschedule_unique_ids_spec(:at)
153
- end
154
-
155
- it "sustains frequent schedule/unschedule 'every' jobs unique ids" do
156
- schedule_unschedule_unique_ids_spec(:every)
157
- end
158
- end
159
-
data/spec/timeout_spec.rb DELETED
@@ -1,148 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Sun May 3 15:44:28 JST 2009
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe "#{SCHEDULER_CLASS} timeouts" do
12
-
13
- before(:each) do
14
- @s = start_scheduler
15
- end
16
- after(:each) do
17
- stop_scheduler(@s)
18
- end
19
-
20
- it 'refuses to schedule a job with :timeout and :blocking' do
21
-
22
- lambda {
23
- @s.in '1s', :timeout => '3s', :blocking => true do
24
- end
25
- }.should raise_error(ArgumentError)
26
- end
27
-
28
- it 'schedules a dedicated job for the timeout' do
29
-
30
- @s.in '1s', :timeout => '3s' do
31
- sleep 5
32
- end
33
-
34
- @s.jobs.size.should == 1
35
-
36
- # the timeout job is left
37
-
38
- sleep 2
39
- @s.jobs.size.should == 1
40
- @s.find_by_tag('timeout').size.should == 1
41
- end
42
-
43
- it 'times out' do
44
-
45
- var = nil
46
- timedout = false
47
-
48
- @s.in '1s', :timeout => '1s' do
49
- begin
50
- sleep 2
51
- var = true
52
- rescue Rufus::Scheduler::TimeOutError => e
53
- timedout = true
54
- end
55
- end
56
-
57
- sleep 4
58
-
59
- var.should == nil
60
- @s.jobs.size.should == 0
61
- timedout.should == true
62
- end
63
-
64
- it 'dies silently if job finished before timeout' do
65
-
66
- var = nil
67
- timedout = false
68
-
69
- @s.in '1s', :timeout => '1s' do
70
- begin
71
- var = true
72
- rescue Rufus::Scheduler::TimeOutError => e
73
- timedout = true
74
- end
75
- end
76
-
77
- sleep 3
78
-
79
- var.should == true
80
- @s.jobs.size.should == 0
81
- timedout.should == false
82
- end
83
-
84
- it 'does not timeout other jobs (in case of every)' do
85
-
86
- timeouts = []
87
-
88
- @s.every '1s', :timeout => '1s500' do
89
- start = Time.now
90
- begin
91
- sleep 2.0
92
- rescue Rufus::Scheduler::TimeOutError => e
93
- timeouts << (Time.now - start)
94
- end
95
- end
96
-
97
- sleep 5.5
98
-
99
- timeouts.size.should == 3
100
- timeouts.each { |to| to.should be_within(0.5).of(1.5) }
101
- end
102
-
103
- it 'points to their "parent" job' do
104
-
105
- @s.in '1s', :timeout => '3s', :job_id => 'nada' do
106
- sleep 4
107
- end
108
-
109
- sleep 2
110
-
111
- @s.jobs.values.first.parent.job_id.should == 'nada'
112
- end
113
-
114
- it 'does not survive their job' do
115
-
116
- @s.in '1s', :timeout => '3s' do
117
- sleep 0.100
118
- end
119
-
120
- sleep 2
121
-
122
- @s.jobs.size.should == 0
123
- end
124
-
125
- it 'times out properly after waiting for a mutex' do
126
-
127
- mutex = Mutex.new
128
- timedout = false
129
-
130
- @s.in '0s', :mutex => mutex do
131
- sleep 1
132
- end
133
-
134
- @s.in '0s', :mutex => mutex, :timeout => 0.1 do
135
- begin
136
- sleep 2
137
- rescue Rufus::Scheduler::TimeOutError => e
138
- timedout = true
139
- end
140
- end
141
-
142
- sleep 2
143
-
144
- @s.jobs.size.should == 0
145
- timedout.should be_true
146
- end
147
- end
148
-