rufus-scheduler 1.0.13 → 1.0.14

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -2,6 +2,12 @@
2
2
  = rufus-scheduler CHANGELOG.txt
3
3
 
4
4
 
5
+ == rufus-scheduler - 1.0.14 released 2009/05/01
6
+
7
+ - bug #25746 : at/every/in scheduling stress issue.
8
+ Fixed by Klaas Jan Wierenga
9
+
10
+
5
11
  == rufus-scheduler - 1.0.13 released 2009/02/02
6
12
 
7
13
  - todo #23779 : removed lib/openwfe/ and restructured to lib/rufus/scheduler/
data/CREDITS.txt CHANGED
@@ -3,6 +3,7 @@
3
3
 
4
4
  == Contributors
5
5
 
6
+ - Klaas Jan Wierenga, at/every/in stress tests, stress patch
6
7
  - TobyH (http://github.com/tobyh), faster and cleaner CronLine#next_time
7
8
  - Ryan Sonnek (http://github.com/wireframe), gemspec
8
9
 
data/LICENSE.txt CHANGED
@@ -1,5 +1,5 @@
1
1
 
2
- Copyright (c) 2005-2008, John Mettraux, jmettraux@gmail.com
2
+ Copyright (c) 2005-2009, John Mettraux, jmettraux@gmail.com
3
3
 
4
4
  Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  of this software and associated documentation files (the "Software"), to deal
data/README.txt CHANGED
@@ -17,6 +17,8 @@ http://rubyforge.org/frs/?group_id=4812
17
17
 
18
18
  == usage
19
19
 
20
+ (the rdoc is at http://rufus.rubyforge.org/rufus-scheduler/)
21
+
20
22
  some examples :
21
23
 
22
24
  require 'rubygems'
@@ -65,7 +67,7 @@ Apart from scheduling, There are also two interesting methods in this gem, they
65
67
  Rufus.to_time_string 7 * 24 * 3600 # => '1w'
66
68
 
67
69
 
68
- Something about the rufus-scheduler, threads and ActiveRecord connections :
70
+ Something about the rufus-scheduler, threads and ActiveRecord connections (warning : I'm mostly clueless about Rails) :
69
71
 
70
72
  http://jmettraux.wordpress.com/2008/09/14/the-scheduler-and-the-active_record/
71
73
 
@@ -1,6 +1,5 @@
1
- #
2
1
  #--
3
- # Copyright (c) 2006-2008, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
4
3
  #
5
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
6
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -19,14 +18,10 @@
19
18
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
20
  # THE SOFTWARE.
22
- #++
23
21
  #
22
+ # Made in Japan.
23
+ #++
24
24
 
25
- #
26
- # "made in Japan"
27
- #
28
- # John Mettraux at openwfe.org
29
- #
30
25
 
31
26
  module Rufus
32
27
 
@@ -166,124 +161,124 @@ module Rufus
166
161
 
167
162
  private
168
163
 
169
- #--
170
- # adjust values to Ruby
164
+ #--
165
+ # adjust values to Ruby
166
+ #
167
+ #def adjust_arrays()
168
+ # @hours = @hours.collect { |h|
169
+ # if h == 24
170
+ # 0
171
+ # else
172
+ # h
173
+ # end
174
+ # } if @hours
175
+ # @weekdays = @weekdays.collect { |wd|
176
+ # wd - 1
177
+ # } if @weekdays
178
+ #end
179
+ #
180
+ # dead code, keeping it as a reminder
181
+ #++
182
+
183
+ WDS = %w[ sun mon tue wed thu fri sat ]
171
184
  #
172
- #def adjust_arrays()
173
- # @hours = @hours.collect { |h|
174
- # if h == 24
175
- # 0
176
- # else
177
- # h
178
- # end
179
- # } if @hours
180
- # @weekdays = @weekdays.collect { |wd|
181
- # wd - 1
182
- # } if @weekdays
183
- #end
184
- #
185
- # dead code, keeping it as a reminder
186
- #++
187
-
188
- WDS = [ "sun", "mon", "tue", "wed", "thu", "fri", "sat" ]
189
- #
190
- # used by parse_weekday()
191
-
192
- def parse_weekdays (item)
193
-
194
- item = item.downcase
195
-
196
- WDS.each_with_index do |day, index|
197
- item = item.gsub day, "#{index}"
198
- end
185
+ # used by parse_weekday()
199
186
 
200
- r = parse_item item, 0, 7
187
+ def parse_weekdays (item)
201
188
 
202
- return r unless r.is_a?(Array)
189
+ item = item.downcase
203
190
 
204
- r.collect { |e| e == 7 ? 0 : e }.uniq
191
+ WDS.each_with_index do |day, index|
192
+ item = item.gsub day, "#{index}"
205
193
  end
206
194
 
207
- def parse_item (item, min, max)
195
+ r = parse_item item, 0, 7
208
196
 
209
- return nil \
210
- if item == "*"
211
- return parse_list(item, min, max) \
212
- if item.index(",")
213
- return parse_range(item, min, max) \
214
- if item.index("*") or item.index("-")
197
+ return r unless r.is_a?(Array)
215
198
 
216
- i = Integer(item)
199
+ r.collect { |e| e == 7 ? 0 : e }.uniq
200
+ end
217
201
 
218
- i = min if i < min
219
- i = max if i > max
202
+ def parse_item (item, min, max)
220
203
 
221
- [ i ]
222
- end
204
+ return nil \
205
+ if item == "*"
206
+ return parse_list(item, min, max) \
207
+ if item.index(",")
208
+ return parse_range(item, min, max) \
209
+ if item.index("*") or item.index("-")
223
210
 
224
- def parse_list (item, min, max)
211
+ i = Integer(item)
225
212
 
226
- items = item.split(",")
213
+ i = min if i < min
214
+ i = max if i > max
227
215
 
228
- items.inject([]) { |r, i| r.push(parse_range(i, min, max)) }.flatten
229
- end
216
+ [ i ]
217
+ end
230
218
 
231
- def parse_range (item, min, max)
219
+ def parse_list (item, min, max)
232
220
 
233
- i = item.index("-")
234
- j = item.index("/")
221
+ items = item.split(",")
235
222
 
236
- return item.to_i if (not i and not j)
223
+ items.inject([]) { |r, i| r.push(parse_range(i, min, max)) }.flatten
224
+ end
225
+
226
+ def parse_range (item, min, max)
237
227
 
238
- inc = 1
228
+ i = item.index("-")
229
+ j = item.index("/")
239
230
 
240
- inc = Integer(item[j+1..-1]) if j
231
+ return item.to_i if (not i and not j)
241
232
 
242
- istart = -1
243
- iend = -1
233
+ inc = 1
244
234
 
245
- if i
235
+ inc = Integer(item[j+1..-1]) if j
246
236
 
247
- istart = Integer(item[0..i-1])
237
+ istart = -1
238
+ iend = -1
248
239
 
249
- if j
250
- iend = Integer(item[i+1..j])
251
- else
252
- iend = Integer(item[i+1..-1])
253
- end
240
+ if i
254
241
 
255
- else # case */x
242
+ istart = Integer(item[0..i-1])
256
243
 
257
- istart = min
258
- iend = max
244
+ if j
245
+ iend = Integer(item[i+1..j])
246
+ else
247
+ iend = Integer(item[i+1..-1])
259
248
  end
260
249
 
261
- istart = min if istart < min
262
- iend = max if iend > max
250
+ else # case */x
263
251
 
264
- result = []
252
+ istart = min
253
+ iend = max
254
+ end
265
255
 
266
- value = istart
267
- loop do
256
+ istart = min if istart < min
257
+ iend = max if iend > max
268
258
 
269
- result << value
270
- value = value + inc
271
- break if value > iend
272
- end
259
+ result = []
273
260
 
274
- result
275
- end
261
+ value = istart
262
+ loop do
276
263
 
277
- def sub_match? value, values
278
- values.nil? || values.include?(value)
264
+ result << value
265
+ value = value + inc
266
+ break if value > iend
279
267
  end
280
268
 
281
- def date_match? date
282
- return false unless sub_match? date.day, @days
283
- return false unless sub_match? date.month, @months
284
- return false unless sub_match? date.wday, @weekdays
285
- true
286
- end
269
+ result
270
+ end
271
+
272
+ def sub_match? value, values
273
+ values.nil? || values.include?(value)
274
+ end
275
+
276
+ def date_match? date
277
+ return false unless sub_match? date.day, @days
278
+ return false unless sub_match? date.month, @months
279
+ return false unless sub_match? date.wday, @weekdays
280
+ true
281
+ end
287
282
  end
288
283
 
289
284
  end
@@ -1,4 +1,3 @@
1
- #
2
1
  #--
3
2
  # Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
4
3
  #
@@ -19,14 +18,10 @@
19
18
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
20
  # THE SOFTWARE.
22
- #++
23
21
  #
22
+ # Made in Japan.
23
+ #++
24
24
 
25
- #
26
- # "made in Japan"
27
- #
28
- # John Mettraux at openwfe.org
29
- #
30
25
 
31
26
  module Rufus
32
27
 
@@ -1,4 +1,3 @@
1
- #
2
1
  #--
3
2
  # Copyright (c) 2005-2009, John Mettraux, jmettraux@gmail.com
4
3
  #
@@ -19,14 +18,10 @@
19
18
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
20
  # THE SOFTWARE.
22
- #++
23
21
  #
22
+ # Hecho en Costa Rica.
23
+ #++
24
24
 
25
- #
26
- # "hecho en Costa Rica"
27
- #
28
- # john.mettraux@openwfe.org
29
- #
30
25
 
31
26
  require 'date'
32
27
  #require 'parsedate'
@@ -80,9 +75,9 @@ module Rufus
80
75
  #
81
76
  # Returns a Ruby time
82
77
  #
83
- def Rufus.to_ruby_time (iso_date)
78
+ def Rufus.to_ruby_time (sdate)
84
79
 
85
- DateTime.parse(iso_date)
80
+ DateTime.parse(sdate)
86
81
  end
87
82
 
88
83
  #def Rufus.parse_date (date)
@@ -162,17 +157,17 @@ module Rufus
162
157
  alias_method :parse_duration_string, :parse_time_string
163
158
  end
164
159
 
165
- #
160
+ #--
166
161
  # Returns true if the character c is a digit
167
162
  #
168
163
  # (probably better served by a regex)
169
164
  #
170
- def Rufus.is_digit? (c)
171
-
172
- return false if not c.kind_of?(String)
173
- return false if c.length > 1
174
- (c >= '0' and c <= '9')
175
- end
165
+ #def Rufus.is_digit? (c)
166
+ # return false if not c.kind_of?(String)
167
+ # return false if c.length > 1
168
+ # (c >= '0' and c <= '9')
169
+ #end
170
+ #++
176
171
 
177
172
  #
178
173
  # conversion methods between Date[Time] and Time
@@ -352,24 +347,24 @@ module Rufus
352
347
 
353
348
  protected
354
349
 
355
- DURATIONS2M = [
356
- [ 'y', 365 * 24 * 3600 ],
357
- [ 'M', 30 * 24 * 3600 ],
358
- [ 'w', 7 * 24 * 3600 ],
359
- [ 'd', 24 * 3600 ],
360
- [ 'h', 3600 ],
361
- [ 'm', 60 ],
362
- [ 's', 1 ]
363
- ]
364
- DURATIONS2 = DURATIONS2M.dup
365
- DURATIONS2.delete_at(1)
366
-
367
- DURATIONS = DURATIONS2M.inject({}) do |r, (k, v)|
368
- r[k] = v
369
- r
370
- end
350
+ DURATIONS2M = [
351
+ [ 'y', 365 * 24 * 3600 ],
352
+ [ 'M', 30 * 24 * 3600 ],
353
+ [ 'w', 7 * 24 * 3600 ],
354
+ [ 'd', 24 * 3600 ],
355
+ [ 'h', 3600 ],
356
+ [ 'm', 60 ],
357
+ [ 's', 1 ]
358
+ ]
359
+ DURATIONS2 = DURATIONS2M.dup
360
+ DURATIONS2.delete_at(1)
361
+
362
+ DURATIONS = DURATIONS2M.inject({}) do |r, (k, v)|
363
+ r[k] = v
364
+ r
365
+ end
371
366
 
372
- DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
367
+ DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
373
368
 
374
369
  end
375
370
 
@@ -1,4 +1,3 @@
1
- #
2
1
  #--
3
2
  # Copyright (c) 2006-2009, John Mettraux, jmettraux@gmail.com
4
3
  #
@@ -19,14 +18,10 @@
19
18
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
19
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
20
  # THE SOFTWARE.
22
- #++
23
21
  #
22
+ # Made in Japan.
23
+ #++
24
24
 
25
- #
26
- # "made in Japan"
27
- #
28
- # John Mettraux at openwfe.org
29
- #
30
25
 
31
26
  require 'thread'
32
27
  require 'rufus/scheduler/otime'
@@ -339,7 +334,7 @@ module Rufus
339
334
  #
340
335
  class Scheduler
341
336
 
342
- VERSION = '1.0.13'
337
+ VERSION = '1.0.14'
343
338
 
344
339
  #
345
340
  # By default, the precision is 0.250, with means the scheduler
@@ -378,8 +373,10 @@ module Rufus
378
373
  @cron_jobs = {}
379
374
  @non_cron_jobs = {}
380
375
 
381
- @schedule_queue = Queue.new
382
- @unschedule_queue = Queue.new
376
+ # @schedule_queue = Queue.new
377
+ # @unschedule_queue = Queue.new
378
+
379
+ @edit_queue = Queue.new
383
380
  #
384
381
  # sync between the step() method and the [un]schedule
385
382
  # methods is done via these queues, no more mutex
@@ -655,7 +652,8 @@ module Rufus
655
652
  b = to_block(params, &block)
656
653
  job = CronJob.new(self, cron_id, cron_line, params, &b)
657
654
 
658
- @schedule_queue << job
655
+ # @schedule_queue << job
656
+ @edit_queue << [ :schedule, job ]
659
657
 
660
658
  job.job_id
661
659
  end
@@ -677,7 +675,7 @@ module Rufus
677
675
  #
678
676
  def unschedule (job_id)
679
677
 
680
- @unschedule_queue << job_id
678
+ @edit_queue << [ :unschedule, job_id ]
681
679
  end
682
680
 
683
681
  #
@@ -842,14 +840,16 @@ module Rufus
842
840
 
843
841
  job.trigger() unless params[:discard_past]
844
842
 
845
- @non_cron_jobs.delete job.job_id # just to be sure
843
+ # change to @non_cron_jobs must be executed on scheduler thread (in step_schedule)
844
+ # @non_cron_jobs.delete(job.job_id) # just to be sure
846
845
 
847
846
  return nil
848
847
  end
849
848
 
850
- @non_cron_jobs[job.job_id] = job
849
+ # change to @non_cron_jobs must be executed on scheduler thread (in step_schedule)
850
+ # @non_cron_jobs[job.job_id] = job
851
851
 
852
- @schedule_queue << job
852
+ @edit_queue << [ :schedule, job ]
853
853
 
854
854
  job.job_id
855
855
  end
@@ -924,55 +924,60 @@ module Rufus
924
924
  #
925
925
  def step
926
926
 
927
- step_unschedule
928
- # unschedules any job in the unschedule queue before
929
- # they have a chance to get triggered.
927
+ step_edit
928
+ # handle ops in the edit_queue
929
+ # this ensures that schedule and unschedule requests are processed
930
+ # in order
930
931
 
931
932
  step_trigger
932
933
  # triggers eligible jobs
933
934
 
934
- step_schedule
935
- # schedule new jobs
936
-
937
935
  # done.
938
936
  end
939
937
 
940
938
  #
941
- # unschedules jobs in the unschedule_queue
942
- #
943
- def step_unschedule
944
-
945
- loop do
946
-
947
- break if @unschedule_queue.empty?
948
-
949
- do_unschedule(@unschedule_queue.pop)
950
- end
951
- end
952
-
953
- #
954
- # adds every job waiting in the @schedule_queue to
955
- # either @pending_jobs or @cron_jobs.
939
+ # schedules or unschedules job in the edit_queue
940
+ # schedule's and unschedule are processed in order
956
941
  #
957
- def step_schedule
958
-
942
+ def step_edit
959
943
  loop do
944
+ break if @edit_queue.empty?
945
+ op, j = @edit_queue.pop
960
946
 
961
- break if @schedule_queue.empty?
962
-
963
- j = @schedule_queue.pop
947
+ case op
948
+ when :schedule
949
+ if j.is_a?(CronJob)
964
950
 
965
- if j.is_a?(CronJob)
951
+ @cron_jobs[j.job_id] = j
966
952
 
967
- @cron_jobs[j.job_id] = j
953
+ else # it's an 'at' job
968
954
 
969
- else # it's an 'at' job
955
+ # add job to @non_cron_jobs
956
+ @non_cron_jobs[j.job_id] = j
957
+ push_pending_job j
970
958
 
971
- push_pending_job j
959
+ end
960
+ when :unschedule
961
+ do_unschedule(j)
962
+ else
963
+ raise ArgumentError
972
964
  end
973
965
  end
974
966
  end
975
967
 
968
+ #
969
+ # unschedules jobs in the unschedule_queue
970
+ #
971
+ # def step_unschedule
972
+ #
973
+ # loop do
974
+ #
975
+ # break if @unschedule_queue.empty?
976
+ #
977
+ # do_unschedule(@unschedule_queue.pop)
978
+ # end
979
+ # end
980
+
976
981
  #
977
982
  # triggers every eligible pending (at or every) jobs, then every eligible
978
983
  # cron jobs.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rufus-scheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.13
4
+ version: 1.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mettraux
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-02-02 00:00:00 +09:00
12
+ date: 2009-05-01 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -37,6 +37,8 @@ files:
37
37
  - README.txt
38
38
  has_rdoc: true
39
39
  homepage: http://openwferu.rubyforge.org/scheduler.html
40
+ licenses: []
41
+
40
42
  post_install_message:
41
43
  rdoc_options: []
42
44
 
@@ -57,9 +59,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
59
  requirements: []
58
60
 
59
61
  rubyforge_project: rufus
60
- rubygems_version: 1.3.1
62
+ rubygems_version: 1.3.2
61
63
  signing_key:
62
- specification_version: 2
64
+ specification_version: 3
63
65
  summary: scheduler for Ruby (at, cron and every jobs), formerly known as 'openwferu-scheduler'
64
66
  test_files:
65
67
  - test/test.rb