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
data/spec/at_in_spec.rb DELETED
@@ -1,47 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Sun Mar 22 16:47:28 JST 2009
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
-
21
- it 'overrides jobs with the same id' do
22
-
23
- hits = []
24
-
25
- job0 = @s.in '1s', :job_id => 'nada' do
26
- hits << 0
27
- end
28
-
29
- wait_next_tick
30
-
31
- job1 = @s.in '1s', :job_id => 'nada' do
32
- hits << 1
33
- end
34
-
35
- wait_next_tick
36
- @s.jobs.size.should == 1
37
-
38
- hits.should == []
39
-
40
- sleep 1.5
41
-
42
- hits.should == [ 1 ]
43
-
44
- @s.jobs.size.should == 0
45
- end
46
- end
47
-
data/spec/at_spec.rb DELETED
@@ -1,125 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Sat Mar 21 20:19:30 JST 2009
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe "#{SCHEDULER_CLASS}#schedule_at" 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.at(Time.now + 1) {}
23
- j0.job_id.should match(/Rufus::Scheduler::AtJob/)
24
- end
25
-
26
- it "accepts integers as 'at'" do
27
-
28
- lambda { @s.at(1) {} }.should_not raise_error
29
- end
30
-
31
- it "schedules at 'top + 1'" do
32
-
33
- var = nil
34
-
35
- @s.at Time.now + 1 do
36
- var = true
37
- end
38
-
39
- var.should == nil
40
- sleep 1.5
41
-
42
- var.should == true
43
- @s.jobs.should == {}
44
- end
45
-
46
- it 'triggers immediately jobs in the past' do
47
-
48
- var = nil
49
-
50
- j = @s.at Time.now - 2 do
51
- var = true
52
- end
53
-
54
- j.should_not == nil
55
-
56
- #wait_next_tick
57
- sleep 0.500
58
-
59
- var.should == true
60
- @s.jobs.should == {}
61
- end
62
-
63
- it 'unschedules (job_id)' do
64
-
65
- job = @s.at Time.now + 3 * 3600 do
66
- end
67
-
68
- sleep 0.300
69
-
70
- @s.jobs.size.should == 1
71
-
72
- @s.unschedule(job.job_id)
73
-
74
- @s.jobs.size.should == 0
75
- end
76
-
77
- it 'unschedules (job)' do
78
-
79
- job = @s.at Time.now + 3 * 3600 do
80
- end
81
-
82
- sleep 0.300
83
-
84
- @s.jobs.size.should == 1
85
-
86
- @s.unschedule(job)
87
-
88
- @s.jobs.size.should == 0
89
- end
90
-
91
- it 'accepts tags for jobs' do
92
-
93
- job = @s.at Time.now + 3 * 3600, :tags => 'spec' do
94
- end
95
-
96
- wait_next_tick
97
-
98
- @s.find_by_tag('spec').size.should == 1
99
- @s.find_by_tag('spec').first.job_id.should == job.job_id
100
- end
101
-
102
- it 'accepts unschedule_by_tag' do
103
-
104
- 3.times do
105
- @s.at Time.now + 3 * 3600, :tags => 'spec' do
106
- end
107
- end
108
-
109
- sleep 0.500
110
-
111
- r = @s.unschedule_by_tag('spec')
112
-
113
- r.size.should == 3
114
- r.first.class.should == Rufus::Scheduler::AtJob
115
- end
116
-
117
- it 'raises on unknown options' do
118
-
119
- lambda {
120
- @s.at Time.now + 3600, :first_at => (Time.now + 3600).to_s do
121
- end
122
- }.should raise_error(ArgumentError)
123
- end
124
- end
125
-
@@ -1,64 +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 do
12
-
13
- before(:each) do
14
- @s = start_scheduler
15
- end
16
- after(:each) do
17
- stop_scheduler(@s)
18
- end
19
-
20
- JOB =
21
- Proc.new do |x|
22
- begin
23
- $var << "a#{x}"
24
- sleep 0.500
25
- $var << "b#{x}"
26
- rescue Exception => e
27
- puts '=' * 80
28
- p e
29
- puts '=' * 80
30
- end
31
- end
32
-
33
- context ':blocking => nil' do
34
-
35
- it "doesn't block" do
36
-
37
- $var = []
38
- @s.in('1s') { JOB.call(1) }
39
- @s.in('1s') { JOB.call(2) }
40
-
41
- sleep 4.0
42
-
43
- [
44
- %w{ a1 a2 b1 b2 }, %w{ a1 a2 b2 b1 },
45
- %w{ a2 a1 b2 b1 }, %w{ a2 a1 b1 b2 }
46
- ].should include($var)
47
- end
48
- end
49
-
50
- context ':blocking => true' do
51
-
52
- it 'blocks' do
53
-
54
- $var = []
55
- @s.in('1s', :blocking => true) { JOB.call(8) }
56
- @s.in('1s', :blocking => true) { JOB.call(9) }
57
-
58
- sleep 4.5
59
-
60
- $var.should == %w[ a8 b8 a9 b9 ]
61
- end
62
- end
63
- end
64
-
data/spec/cron_spec.rb DELETED
@@ -1,134 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Sun Mar 22 19:59:12 JST 2009
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe "#{SCHEDULER_CLASS}#cron" 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.cron('7 10-12 * * * *') {}
23
- j0.job_id.should match(/Rufus::Scheduler::CronJob/)
24
- end
25
-
26
- it 'crons every second' do
27
-
28
- seconds = []
29
-
30
- job = @s.cron '* * * * * *' do |job|
31
- seconds << job.last.sec
32
- end
33
- sleep 4.990
34
-
35
- job.unschedule
36
-
37
- seconds.uniq.size.should == seconds.size
38
- end
39
-
40
- it 'unschedules (self)' do
41
-
42
- second = nil
43
-
44
- job = @s.cron '* * * * * *' do |job|
45
- second = job.last.sec
46
- end
47
-
48
- second.should == nil
49
-
50
- sleep 2
51
-
52
- second.should_not == nil
53
-
54
- job.unschedule
55
-
56
- after = second
57
-
58
- sleep 2
59
-
60
- second.should == after
61
- end
62
-
63
- it 'unschedules (job)' do
64
-
65
- second = nil
66
-
67
- job = @s.cron '* * * * * *' do |job|
68
- second = job.last.sec
69
- end
70
-
71
- second.should == nil
72
-
73
- sleep 2
74
-
75
- second.should_not == nil
76
-
77
- @s.unschedule(job)
78
-
79
- after = second
80
-
81
- sleep 2
82
-
83
- second.should == after
84
- end
85
-
86
- it 'keeps track of cron jobs' do
87
-
88
- j0 = @s.cron '7 10-12 * * * *' do
89
- end
90
- j1 = @s.cron '7 10-12 * * * *' do
91
- end
92
-
93
- @s.cron_jobs.keys.sort.should == [ j0.job_id, j1.job_id ].sort
94
- end
95
-
96
- it 'accepts tags for jobs' do
97
-
98
- job = @s.cron '* * * * * *', :tags => 'spec' do
99
- end
100
-
101
- wait_next_tick
102
-
103
- @s.find_by_tag('spec').size.should == 1
104
- @s.find_by_tag('spec').first.job_id.should == job.job_id
105
- end
106
-
107
- it 'accepts job.unschedule within the job' do
108
-
109
- stack = []
110
-
111
- @s.cron '* * * * * *' do |job|
112
- if stack.size > 2
113
- stack << 'done'
114
- job.unschedule
115
- else
116
- stack << 'ok'
117
- end
118
- end
119
-
120
- sleep 4
121
-
122
- @s.jobs.size.should == 0
123
- stack.should == %w[ ok ok ok done ]
124
- end
125
-
126
- it 'raises on unknown options' do
127
-
128
- lambda {
129
- @s.cron '* * * * *', :pool => :party do
130
- end
131
- }.should raise_error(ArgumentError)
132
- end
133
- end
134
-
data/spec/every_spec.rb DELETED
@@ -1,304 +0,0 @@
1
-
2
- #
3
- # Specifying rufus-scheduler
4
- #
5
- # Sun Mar 22 12:26:07 JST 2009
6
- #
7
-
8
- require 'spec_base'
9
-
10
-
11
- describe "#{SCHEDULER_CLASS}#every" 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.every(1) {}
23
- j0.job_id.should match(/Rufus::Scheduler::EveryJob/)
24
- end
25
-
26
- it 'computes frequency' do
27
-
28
- job = @s.every '2h1m' do
29
- end
30
- job.frequency.should == 7260
31
- end
32
-
33
- it 'schedules every 1s' do
34
-
35
- var = 0
36
-
37
- job = @s.every '1s' do
38
- var += 1
39
- end
40
-
41
- sleep 3.7
42
-
43
- var.should == 3
44
- end
45
-
46
- it 'schedules every 0.1s' do
47
-
48
- var = 0
49
-
50
- job = @s.every '0.1s' do
51
- var += 1
52
- end
53
-
54
- sleep 3.7
55
-
56
- var.should be_within(10).of(37)
57
- end
58
-
59
- it 'raises on schedule every 0s' do
60
-
61
- lambda {
62
- @s.every '0s' do
63
- end
64
- }.should raise_error(ArgumentError)
65
- end
66
-
67
- it 'raises on schedule every -1s' do
68
-
69
- lambda {
70
- @s.every '-1s' do
71
- end
72
- }.should raise_error(ArgumentError)
73
- end
74
-
75
- it 'raises on schedule every \'\'' do
76
-
77
- lambda {
78
- @s.every '' do
79
- end
80
- }.should raise_error(ArgumentError)
81
- end
82
-
83
- it 'raises on schedule every nil' do
84
-
85
- lambda {
86
- @s.every nil do
87
- end
88
- }.should raise_error(ArgumentError)
89
- end
90
-
91
- it 'is punctilious' do
92
-
93
- hits = []
94
-
95
- job = @s.every '1s' do
96
- hits << Time.now.to_f
97
- end
98
-
99
- sleep 9.9
100
-
101
- hh = nil
102
- deltas = []
103
- hits.each { |h| f = h; deltas << (f - hh) if hh; hh = f }
104
-
105
- #puts; p deltas
106
- deltas.max.should satisfy { |d| d < 1.200 }
107
- end
108
-
109
- it 'unschedules' do
110
-
111
- var = 0
112
-
113
- job = @s.every '1s' do
114
- var += 1
115
- end
116
-
117
- sleep 2.7
118
-
119
- @s.unschedule(job.job_id)
120
-
121
- var.should == 2
122
-
123
- sleep 1.7
124
-
125
- var.should == 2
126
- end
127
-
128
- it 'accepts tags for jobs' do
129
-
130
- job = @s.every '1s', :tags => 'spec' do
131
- end
132
-
133
- wait_next_tick
134
-
135
- @s.find_by_tag('spec').size.should == 1
136
- @s.find_by_tag('spec').first.job_id.should == job.job_id
137
- end
138
-
139
- it 'honours :first_at' do
140
-
141
- counter = 0
142
-
143
- @s.every '1s', :first_at => Time.now + 2 do
144
- counter += 1
145
- end
146
-
147
- sleep 1
148
- counter.should == 0
149
-
150
- sleep 2.5
151
- counter.should == 2
152
- end
153
-
154
- it 'triggers for the missed schedules when :first_at is in the past' do
155
-
156
- counter = 0
157
-
158
- @s.every '1s', :first_at => Time.now - 2 do
159
- counter += 1
160
- end
161
-
162
- wait_next_tick
163
- counter.should == 3
164
- end
165
-
166
- it 'does not trigger for the missed schedules when :first_at is in the past and :discard_past => true' do
167
-
168
- counter = 0
169
-
170
- @s.every '1s', :first_at => Time.now - 2, :discard_past => true do
171
- counter += 1
172
- end
173
-
174
- wait_next_tick
175
- counter.should == 0
176
- end
177
-
178
- it 'honours :first_in' do
179
-
180
- counter = 0
181
-
182
- @s.every '1s', :first_in => 2 do
183
- counter += 1
184
- end
185
-
186
- sleep 1
187
- counter.should == 0
188
-
189
- sleep 2.5
190
- counter.should == 2
191
- end
192
-
193
- #it 'honours :dont_reschedule' do
194
- # stack = []
195
- # @s.every 0.400 do |job|
196
- # if stack.size > 3
197
- # stack << 'done'
198
- # job.params[:dont_reschedule] = true
199
- # else
200
- # stack << 'ok'
201
- # end
202
- # end
203
- # sleep 4
204
- # @s.jobs.size.should.equal(0)
205
- # stack.should.equal(%w[ ok ok ok ok done ])
206
- #end
207
-
208
- it 'accepts job.unschedule within the job' do
209
-
210
- stack = []
211
-
212
- @s.every 0.400 do |job|
213
- if stack.size > 3
214
- stack << 'done'
215
- job.unschedule
216
- else
217
- stack << 'ok'
218
- end
219
- end
220
-
221
- sleep 4
222
-
223
- @s.jobs.size.should == 0
224
- stack.should == %w[ ok ok ok ok done ]
225
- end
226
-
227
- it 'respects :blocking => true' do
228
-
229
- stack = []
230
-
231
- @s.every '1s', :blocking => true do |job|
232
- stack << 'ok'
233
- sleep 2
234
- end
235
-
236
- sleep 5
237
-
238
- stack.should == %w[ ok ok ]
239
- end
240
-
241
- it 'lists the "trigger threads"' do
242
-
243
- @s.every '1s' do
244
- sleep 10
245
- end
246
- sleep 5
247
-
248
- @s.trigger_threads.size.should == 4
249
- end
250
-
251
- it "doesn't allow overlapped execution if :allow_overlapping => false" do
252
-
253
- stack = []
254
-
255
- @s.every '1s', :allow_overlapping => false do |job|
256
- stack << 'ok'
257
- sleep 2
258
- end
259
-
260
- sleep 5
261
-
262
- stack.size.should == 2
263
- end
264
-
265
- it 'allows overlapped execution by default' do
266
-
267
- stack = []
268
-
269
- @s.every '1s' do |job|
270
- stack << 'ok'
271
- sleep 2
272
- end
273
-
274
- sleep 5
275
-
276
- stack.size.should == 4
277
- end
278
-
279
- it 'schedules anyway when exception and :allow_overlapping => false' do
280
-
281
- $exceptions = []
282
-
283
- def @s.handle_exception(job, exception)
284
- $exceptions << exception
285
- end
286
-
287
- @s.every '1s', :allow_overlapping => false do
288
- raise 'fail'
289
- end
290
-
291
- sleep 4
292
-
293
- $exceptions.size.should be > 1
294
- end
295
-
296
- it 'raises on unknown options' do
297
-
298
- lambda {
299
- @s.every '1s', :pool => :party do
300
- end
301
- }.should raise_error(ArgumentError)
302
- end
303
- end
304
-