rufus-scheduler 1.0.13 → 1.0.14

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.
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