rufus-scheduler 2.0.24 → 3.0.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.
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
-