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