rufus-scheduler 2.0.24 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/CHANGELOG.txt +76 -0
  2. data/CREDITS.txt +23 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1439 -0
  5. data/Rakefile +1 -5
  6. data/TODO.txt +149 -55
  7. data/lib/rufus/{sc → scheduler}/cronline.rb +167 -53
  8. data/lib/rufus/scheduler/job_array.rb +92 -0
  9. data/lib/rufus/scheduler/jobs.rb +633 -0
  10. data/lib/rufus/scheduler/locks.rb +95 -0
  11. data/lib/rufus/scheduler/util.rb +306 -0
  12. data/lib/rufus/scheduler/zones.rb +174 -0
  13. data/lib/rufus/scheduler/zotime.rb +154 -0
  14. data/lib/rufus/scheduler.rb +608 -27
  15. data/rufus-scheduler.gemspec +6 -4
  16. data/spec/basics_spec.rb +54 -0
  17. data/spec/cronline_spec.rb +479 -152
  18. data/spec/error_spec.rb +139 -0
  19. data/spec/job_array_spec.rb +39 -0
  20. data/spec/job_at_spec.rb +58 -0
  21. data/spec/job_cron_spec.rb +128 -0
  22. data/spec/job_every_spec.rb +104 -0
  23. data/spec/job_in_spec.rb +20 -0
  24. data/spec/job_interval_spec.rb +68 -0
  25. data/spec/job_repeat_spec.rb +357 -0
  26. data/spec/job_spec.rb +498 -109
  27. data/spec/lock_custom_spec.rb +47 -0
  28. data/spec/lock_flock_spec.rb +47 -0
  29. data/spec/lock_lockfile_spec.rb +61 -0
  30. data/spec/lock_spec.rb +59 -0
  31. data/spec/parse_spec.rb +263 -0
  32. data/spec/schedule_at_spec.rb +158 -0
  33. data/spec/schedule_cron_spec.rb +66 -0
  34. data/spec/schedule_every_spec.rb +109 -0
  35. data/spec/schedule_in_spec.rb +80 -0
  36. data/spec/schedule_interval_spec.rb +128 -0
  37. data/spec/scheduler_spec.rb +928 -124
  38. data/spec/spec_helper.rb +126 -0
  39. data/spec/threads_spec.rb +96 -0
  40. data/spec/zotime_spec.rb +396 -0
  41. metadata +56 -33
  42. data/README.rdoc +0 -661
  43. data/lib/rufus/otime.rb +0 -3
  44. data/lib/rufus/sc/jobqueues.rb +0 -160
  45. data/lib/rufus/sc/jobs.rb +0 -471
  46. data/lib/rufus/sc/rtime.rb +0 -363
  47. data/lib/rufus/sc/scheduler.rb +0 -636
  48. data/lib/rufus/sc/version.rb +0 -32
  49. data/spec/at_in_spec.rb +0 -47
  50. data/spec/at_spec.rb +0 -125
  51. data/spec/blocking_spec.rb +0 -64
  52. data/spec/cron_spec.rb +0 -134
  53. data/spec/every_spec.rb +0 -304
  54. data/spec/exception_spec.rb +0 -113
  55. data/spec/in_spec.rb +0 -150
  56. data/spec/mutex_spec.rb +0 -159
  57. data/spec/rtime_spec.rb +0 -137
  58. data/spec/schedulable_spec.rb +0 -97
  59. data/spec/spec_base.rb +0 -87
  60. data/spec/stress_schedule_unschedule_spec.rb +0 -159
  61. data/spec/timeout_spec.rb +0 -148
  62. data/test/kjw.rb +0 -113
  63. data/test/t.rb +0 -20
data/spec/in_spec.rb DELETED
@@ -1,150 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Sat Mar 21 17:36:36 JST 2009
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe "#{SCHEDULER_CLASS}#in" 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 'has job ids with the class name in it' do
21
-
22
- j0 = @s.in(1) {}
23
- j0.job_id.should match(/Rufus::Scheduler::InJob/)
24
- end
25
-
26
- it 'tracks scheduled in jobs' do
27
-
28
- @s.in(1) {}
29
-
30
- wait_next_tick
31
- @s.jobs.size.should == 1
32
-
33
- sleep 1.5
34
-
35
- @s.jobs.size.should == 0
36
- end
37
-
38
- it 'schedules in 1' do
39
-
40
- var = nil
41
-
42
- @s.in 1 do
43
- var = true
44
- end
45
-
46
- var.should == nil
47
- sleep 1.5
48
-
49
- var.should == true
50
- end
51
-
52
- it 'schedules in 1.0' do
53
-
54
- var = nil
55
-
56
- @s.in 1.0 do
57
- var = true
58
- end
59
-
60
- var.should == nil
61
- sleep 1.5
62
-
63
- var.should == true
64
- end
65
-
66
- it 'schedules in 1s' do
67
-
68
- var = nil
69
-
70
- @s.in '1s' do
71
- var = true
72
- end
73
-
74
- var.should == nil
75
- sleep 1.5
76
-
77
- var.should == true
78
- end
79
-
80
- it 'returns the new job' do
81
-
82
- r = @s.in '1s' do
83
- end
84
-
85
- r.class.should == Rufus::Scheduler::InJob
86
- end
87
-
88
- it 'triggers [almost] immediately jobs in the past' do
89
-
90
- var = nil
91
-
92
- r = @s.in -2 do
93
- var = true
94
- end
95
-
96
- #wait_next_tick
97
- sleep 0.550
98
-
99
- r.class.should == Rufus::Scheduler::InJob
100
- var.should == true
101
- @s.jobs.should == {}
102
- end
103
-
104
- it 'does not trigger jobs in the past when :discard_past => true' do
105
-
106
- var = nil
107
-
108
- r = @s.in -2, :discard_past => true do
109
- var = true
110
- end
111
-
112
- r.should == nil
113
- var.should == nil
114
- @s.jobs.should == {}
115
- end
116
-
117
- it 'unschedules jobs' do
118
-
119
- job = @s.in '2d' do
120
- end
121
-
122
- wait_next_tick
123
-
124
- @s.jobs.size.should == 1
125
-
126
- @s.unschedule(job.job_id)
127
-
128
- @s.jobs.size.should == 0
129
- end
130
-
131
- it 'accepts tags for jobs' do
132
-
133
- job = @s.in '2d', :tags => 'spec' do
134
- end
135
-
136
- wait_next_tick
137
-
138
- @s.find_by_tag('spec').size.should == 1
139
- @s.find_by_tag('spec').first.job_id.should == job.job_id
140
- end
141
-
142
- it 'raises on unknown options' do
143
-
144
- lambda {
145
- @s.in '2d', :first_at => (Time.now + 3600).to_s do
146
- end
147
- }.should raise_error(ArgumentError)
148
- end
149
- end
150
-
data/spec/mutex_spec.rb DELETED
@@ -1,159 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Fri Oct 7 17:30:45 JST 2011
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe SCHEDULER_CLASS do
12
-
13
- before(:each) do
14
- @s = start_scheduler
15
- end
16
- after(:each) do
17
- stop_scheduler(@s)
18
- end
19
-
20
- MJOB = Proc.new do |x|
21
- begin
22
- $var << "in#{x}"
23
- sleep 0.500
24
- $var << "out#{x}"
25
- rescue Exception => e
26
- puts '=' * 80
27
- p e
28
- puts '=' * 80
29
- end
30
- end
31
-
32
- context ':mutex => String' do
33
-
34
- it 'prevents overlapping' do
35
-
36
- $var = ''
37
-
38
- @s.in('1s', :mutex => 'toto') { MJOB.call(0) }
39
- @s.in('1s', :mutex => 'toto') { MJOB.call(1) }
40
-
41
- sleep 3.0
42
-
43
- %w[ in0out0in1out1 in1out1in0out0 ].should include($var)
44
- end
45
-
46
- it 'creates a new mutex when the name is first encountered' do
47
-
48
- @s.instance_variable_get(:@mutexes).size.should == 0
49
-
50
- @s.in('1s', :mutex => 'fruit') { sleep 0.1 }
51
-
52
- sleep 1.5
53
-
54
- @s.instance_variable_get(:@mutexes).size.should == 1
55
- end
56
-
57
- it 'creates a unique mutex for a given name' do
58
-
59
- @s.in('1s', :mutex => 'gum') { sleep 0.1 }
60
- @s.in('1s', :mutex => 'gum') { sleep 0.1 }
61
-
62
- sleep 1.5
63
-
64
- @s.instance_variable_get(:@mutexes).size.should == 1
65
- end
66
- end
67
-
68
- context ':mutex => Mutex' do
69
-
70
- it 'prevents overlapping' do
71
-
72
- $var = ''
73
- m = Mutex.new
74
-
75
- @s.in('1s', :mutex => m) { MJOB.call(0) }
76
- @s.in('1s', :mutex => m) { MJOB.call(1) }
77
-
78
- sleep 3.0
79
-
80
- %w[ in0out0in1out1 in1out1in0out0 ].should include($var)
81
- end
82
-
83
- it 'does not register the mutex' do
84
-
85
- @s.in('1s', :mutex => Mutex.new) { sleep 0.1 }
86
-
87
- sleep 1.5
88
-
89
- @s.instance_variable_get(:@mutexes).size.should == 0
90
- end
91
- end
92
-
93
- context ':mutexes => Array of String' do
94
-
95
- it 'ensure exclusivity' do
96
-
97
- $var = ''
98
- m0 = 'm0'
99
- m1 = 'm1'
100
-
101
- @s.in('1s', :mutex => m0) { MJOB.call(0) }
102
- @s.in('1s', :mutex => m1) { MJOB.call(1) }
103
- @s.in('1s', :mutex => [m0, m1]) { MJOB.call(2) }
104
-
105
- sleep 4.5
106
-
107
- $var.should include('in2out2')
108
- end
109
-
110
- it 'creates new mutexes when the names are first encountered' do
111
-
112
- @s.instance_variable_get(:@mutexes).size.should == 0
113
-
114
- @s.in('1s', :mutex => ['fruit', 'bread']) { sleep 0.1 }
115
-
116
- sleep 1.5
117
-
118
- @s.instance_variable_get(:@mutexes).size.should == 2
119
- end
120
-
121
- it 'creates a unique mutex for a given name' do
122
-
123
- @s.in('1s', :mutex => ['fruit', 'bread']) { sleep 0.1 }
124
- @s.in('1s', :mutex => ['fruit', 'bread']) { sleep 0.1 }
125
-
126
- sleep 1.5
127
-
128
- @s.instance_variable_get(:@mutexes).size.should == 2
129
- end
130
- end
131
-
132
- context ':mutexes => Array of Mutex' do
133
-
134
- it 'ensure exclusivity' do
135
-
136
- $var = ''
137
- m0 = Mutex.new
138
- m1 = Mutex.new
139
-
140
- @s.in('1s', :mutex => m0) { MJOB.call(0) }
141
- @s.in('1s', :mutex => m1) { MJOB.call(1) }
142
- @s.in('1s', :mutex => [m0, m1]) { MJOB.call(2) }
143
-
144
- sleep 4.5
145
-
146
- $var.should include('in2out2')
147
- end
148
-
149
- it 'does not register the mutexes' do
150
-
151
- @s.in('1s', :mutex => [Mutex.new, Mutex.new]) { sleep 0.1 }
152
-
153
- sleep 1.5
154
-
155
- @s.instance_variable_get(:@mutexes).size.should == 0
156
- end
157
- end
158
- end
159
-
data/spec/rtime_spec.rb DELETED
@@ -1,137 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Fri Mar 20 23:46:32 JST 2009
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe 'rufus/rtime' do
12
-
13
- def pts(s)
14
- Rufus.parse_time_string(s)
15
- end
16
-
17
- def tts(f, opts={})
18
- Rufus.to_time_string(f, opts)
19
- end
20
-
21
- def tdh(f, opts={})
22
- Rufus.to_duration_hash(f, opts)
23
- end
24
-
25
- it 'parses duration strings' do
26
-
27
- pts('-1.0d1.0w1.0d').should == -777600.0
28
- pts('-1d1w1d').should == -777600.0
29
- pts('-1w2d').should == -777600.0
30
- pts('-1h10s').should == -3610.0
31
- pts('-1h').should == -3600.0
32
- pts('-5.').should == -5.0
33
- pts('-2.5s').should == -2.5
34
- pts('-1s').should == -1.0
35
- pts('-500').should == -0.5
36
- pts('').should == 0.0
37
- pts('5.0').should == 5.0
38
- pts('0.5').should == 0.5
39
- pts('.5').should == 0.5
40
- pts('5.').should == 5.0
41
- pts('500').should == 0.5
42
- pts('1000').should == 1.0
43
- pts('1').should == 0.001
44
- pts('1s').should == 1.0
45
- pts('2.5s').should == 2.5
46
- pts('1h').should == 3600.0
47
- pts('1h10s').should == 3610.0
48
- pts('1w2d').should == 777600.0
49
- pts('1d1w1d').should == 777600.0
50
- pts('1.0d1.0w1.0d').should == 777600.0
51
-
52
- pts('.5m').should == 30.0
53
- pts('5.m').should == 300.0
54
- pts('1m.5s').should == 60.5
55
- pts('-.5m').should == -30.0
56
-
57
- pts('1d').should == 86400.0
58
- pts('0.1d').should == 8640.0
59
- pts('0.1s').should == 0.1
60
-
61
- pts('0.1').should == 0.1
62
- pts('1').should == 0.001
63
- #
64
- # the two evil twins :-(
65
- end
66
-
67
- it 'parses duration "strings"' do
68
-
69
- o = Object.new
70
- def o.to_s; '-2'; end
71
-
72
- pts(o).should == -0.002
73
- end
74
-
75
- it 'raises on wrong duration strings' do
76
-
77
- lambda { pts('-') }.should raise_error(ArgumentError)
78
- lambda { pts('h') }.should raise_error(ArgumentError)
79
- lambda { pts('whatever') }.should raise_error(ArgumentError)
80
- lambda { pts('hms') }.should raise_error(ArgumentError)
81
-
82
- lambda { pts(' 1h ') }.should raise_error(ArgumentError)
83
- end
84
-
85
- it 'generates duration strings' do
86
-
87
- tts(0).should == '0s'
88
- tts(0, :drop_seconds => true).should == '0m'
89
- tts(60).should == '1m'
90
- tts(61).should == '1m1s'
91
- tts(3661).should == '1h1m1s'
92
- tts(24 * 3600).should == '1d'
93
- tts(7 * 24 * 3600 + 1).should == '1w1s'
94
- tts(30 * 24 * 3600 + 1).should == '4w2d1s'
95
- tts(30 * 24 * 3600 + 1, :months => true).should == '1M1s'
96
- end
97
-
98
- it 'computes duration hashes' do
99
-
100
- tdh(0).should == {}
101
- tdh(0.128).should == { :ms => 128 }
102
- tdh(60.127).should == { :m => 1, :ms => 127 }
103
- tdh(61.127).should == { :m => 1, :s => 1, :ms => 127 }
104
- tdh(61.127, :drop_seconds => true).should == { :m => 1 }
105
- end
106
- end
107
-
108
- describe 'Rufus.at_to_f' do
109
-
110
- def atf(o)
111
- Rufus.at_to_f(o)
112
- end
113
-
114
- it 'turns Time at values to float' do
115
-
116
- t = Time.now
117
- tf = t.to_f.to_i.to_f
118
-
119
- atf(t + 2).to_i.to_f.should == tf + 2
120
- end
121
-
122
- it 'turns String at values to float' do
123
-
124
- atf('Sat Mar 21 20:08:01 +0900 2009').should == 1237633681.0
125
- atf('Sat Mar 21 20:08:01 -0900 2009').should == 1237698481.0
126
- atf('Sat Mar 21 20:08:01 +0000 2009').should == 1237666081.0
127
- atf('Sat Mar 21 20:08:01 2009').should == 1237666081.0
128
- atf('Mar 21 20:08:01 2009').should == 1237666081.0
129
- atf('2009/03/21 20:08').should == 1237666080.0
130
- end
131
-
132
- it 'accepts integers' do
133
-
134
- atf(1).should == 1.0
135
- end
136
- end
137
-
@@ -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
-