rufus-scheduler 1.0.12 → 1.0.13

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -1,7 +1,18 @@
1
1
 
2
2
  = rufus-scheduler CHANGELOG.txt
3
3
 
4
- == rufus-scheduler - 1.0.12 not yet released
4
+
5
+ == rufus-scheduler - 1.0.13 released 2009/02/02
6
+
7
+ - todo #23779 : removed lib/openwfe/ and restructured to lib/rufus/scheduler/
8
+ - todo #23774 : adapted to Ruby 1.9.1
9
+ - todo #23483 : removed gemspec from Rakefile
10
+ - bug #23458 : :timeout not working on JRuby (reported by Chris Evans). Fixed.
11
+ - patch #23430 : gemspec patch by Ryan Sonnek
12
+ - patch #23412 : faster CronLine#next_time patch by TobyH
13
+
14
+
15
+ == rufus-scheduler - 1.0.12 released 2008/12/18
5
16
 
6
17
  - todo #23257 : added :timeout parameter for cron/in/at/every
7
18
  - bug #22546 : added note about CronLine#next_time, K Liu
data/CREDITS.txt CHANGED
@@ -1,8 +1,15 @@
1
1
 
2
2
  = CREDITS.txt
3
3
 
4
+ == Contributors
5
+
6
+ - TobyH (http://github.com/tobyh), faster and cleaner CronLine#next_time
7
+ - Ryan Sonnek (http://github.com/wireframe), gemspec
8
+
9
+
4
10
  == Feedback
5
11
 
12
+ - Chris Evans, :timeout tests on JRuby
6
13
  - Tim Uckun, :timeout concept
7
14
  - K Liu, for the note about CronLine#next_time
8
15
  - Xianhang Zhang, find_jobs(tag=nil) patch
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+
2
+ Copyright (c) 2005-2008, John Mettraux, jmettraux@gmail.com
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
data/lib/rufus/otime.rb CHANGED
@@ -1,375 +1,3 @@
1
- #
2
- #--
3
- # Copyright (c) 2005-2008, John Mettraux, jmettraux@gmail.com
4
- #
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be included in
13
- # all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
- # THE SOFTWARE.
22
- #++
23
- #
24
1
 
25
- #
26
- # "hecho en Costa Rica"
27
- #
28
- # john.mettraux@openwfe.org
29
- #
30
-
31
- require 'date'
32
- #require 'parsedate'
33
-
34
-
35
- module Rufus
36
-
37
- #TIME_FORMAT = "%Y-%m-%d %H:%M:%S"
38
-
39
- #
40
- # Returns the current time as an ISO date string
41
- #
42
- def Rufus.now
43
-
44
- to_iso8601_date(Time.new())
45
- end
46
-
47
- #
48
- # As the name implies.
49
- #
50
- def Rufus.to_iso8601_date (date)
51
-
52
- if date.kind_of? Float
53
- date = to_datetime(Time.at(date))
54
- elsif date.kind_of? Time
55
- date = to_datetime(date)
56
- elsif not date.kind_of? Date
57
- date = DateTime.parse(date)
58
- end
59
-
60
- s = date.to_s # this is costly
61
- s[10] = " "
62
-
63
- s
64
- end
65
-
66
- #
67
- # the old method we used to generate our ISO datetime strings
68
- #
69
- def Rufus.time_to_iso8601_date (time)
70
-
71
- s = time.getutc().strftime(TIME_FORMAT)
72
- o = time.utc_offset / 3600
73
- o = o.to_s + "00"
74
- o = "0" + o if o.length < 4
75
- o = "+" + o unless o[0..1] == '-'
76
-
77
- s + " " + o.to_s
78
- end
79
-
80
- #
81
- # Returns a Ruby time
82
- #
83
- def Rufus.to_ruby_time (iso_date)
84
-
85
- DateTime.parse(iso_date)
86
- end
87
-
88
- #def Rufus.parse_date (date)
89
- #end
90
-
91
- #
92
- # equivalent to java.lang.System.currentTimeMillis()
93
- #
94
- def Rufus.current_time_millis
95
-
96
- (Time.new.to_f * 1000).to_i
97
- end
98
-
99
- #
100
- # Turns a string like '1m10s' into a float like '70.0', more formally,
101
- # turns a time duration expressed as a string into a Float instance
102
- # (millisecond count).
103
- #
104
- # w -> week
105
- # d -> day
106
- # h -> hour
107
- # m -> minute
108
- # s -> second
109
- # M -> month
110
- # y -> year
111
- # 'nada' -> millisecond
112
- #
113
- # Some examples :
114
- #
115
- # Rufus.parse_time_string "500" # => 0.5
116
- # Rufus.parse_time_string "1000" # => 1.0
117
- # Rufus.parse_time_string "1h" # => 3600.0
118
- # Rufus.parse_time_string "1h10s" # => 3610.0
119
- # Rufus.parse_time_string "1w2d" # => 777600.0
120
- #
121
- def Rufus.parse_time_string (string)
122
-
123
- string = string.strip
124
-
125
- index = -1
126
- result = 0.0
127
-
128
- number = ""
129
-
130
- loop do
131
-
132
- index = index + 1
133
-
134
- if index >= string.length
135
- result = result + (Float(number) / 1000.0) if number.length > 0
136
- break
137
- end
138
-
139
- c = string[index, 1]
140
-
141
- #if is_digit?(c)
142
- if (c >= "0" and c <= "9")
143
- number = number + c
144
- next
145
- end
146
-
147
- value = Integer(number)
148
- number = ""
149
-
150
- multiplier = DURATIONS[c]
151
-
152
- raise "unknown time char '#{c}'" \
153
- if not multiplier
154
-
155
- result = result + (value * multiplier)
156
- end
157
-
158
- result
159
- end
160
-
161
- class << self
162
- alias_method :parse_duration_string, :parse_time_string
163
- end
164
-
165
- #
166
- # Returns true if the character c is a digit
167
- #
168
- # (probably better served by a regex)
169
- #
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
176
-
177
- #
178
- # conversion methods between Date[Time] and Time
179
-
180
- #
181
- # Ruby Cookbook 1st edition p.111
182
- # http://www.oreilly.com/catalog/rubyckbk/
183
- # a must
184
- #
185
-
186
- #
187
- # converts a Time instance to a DateTime one
188
- #
189
- def Rufus.to_datetime (time)
190
-
191
- s = time.sec + Rational(time.usec, 10**6)
192
- o = Rational(time.utc_offset, 3600 * 24)
193
-
194
- begin
195
-
196
- DateTime.new(
197
- time.year,
198
- time.month,
199
- time.day,
200
- time.hour,
201
- time.min,
202
- s,
203
- o)
204
-
205
- rescue Exception => e
206
-
207
- DateTime.new(
208
- time.year,
209
- time.month,
210
- time.day,
211
- time.hour,
212
- time.min,
213
- time.sec,
214
- time.utc_offset)
215
- end
216
- end
217
-
218
- def Rufus.to_gm_time (dtime)
219
-
220
- to_ttime(dtime.new_offset, :gm)
221
- end
222
-
223
- def Rufus.to_local_time (dtime)
224
-
225
- to_ttime(dtime.new_offset(DateTime.now.offset-offset), :local)
226
- end
227
-
228
- def Rufus.to_ttime (d, method)
229
-
230
- usec = (d.sec_fraction * 3600 * 24 * (10**6)).to_i
231
- Time.send(method, d.year, d.month, d.day, d.hour, d.min, d.sec, usec)
232
- end
233
-
234
- #
235
- # Turns a number of seconds into a a time string
236
- #
237
- # Rufus.to_duration_string 0 # => '0s'
238
- # Rufus.to_duration_string 60 # => '1m'
239
- # Rufus.to_duration_string 3661 # => '1h1m1s'
240
- # Rufus.to_duration_string 7 * 24 * 3600 # => '1w'
241
- # Rufus.to_duration_string 30 * 24 * 3600 + 1 # => "4w2d1s"
242
- #
243
- # It goes from seconds to the year. Months are not counted (as they
244
- # are of variable length). Weeks are counted.
245
- #
246
- # For 30 days months to be counted, the second parameter of this
247
- # method can be set to true.
248
- #
249
- # Rufus.to_time_string 30 * 24 * 3600 + 1, true # => "1M1s"
250
- #
251
- # (to_time_string is an alias for to_duration_string)
252
- #
253
- # If a Float value is passed, milliseconds will be displayed without
254
- # 'marker'
255
- #
256
- # Rufus.to_duration_string 0.051 # =>"51"
257
- # Rufus.to_duration_string 7.051 # =>"7s51"
258
- # Rufus.to_duration_string 0.120 + 30 * 24 * 3600 + 1 # =>"4w2d1s120"
259
- #
260
- # (this behaviour mirrors the one found for parse_time_string()).
261
- #
262
- # Options are :
263
- #
264
- # * :months, if set to true, months (M) of 30 days will be taken into
265
- # account when building up the result
266
- # * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
267
- # from the result
268
- #
269
- def Rufus.to_duration_string (seconds, options={})
270
-
271
- return (options[:drop_seconds] ? '0m' : '0s') if seconds <= 0
272
-
273
- h = to_duration_hash seconds, options
274
-
275
- s = DU_KEYS.inject("") do |r, key|
276
- count = h[key]
277
- count = nil if count == 0
278
- r << "#{count}#{key}" if count
279
- r
280
- end
281
-
282
- ms = h[:ms]
283
- s << ms.to_s if ms
284
-
285
- s
286
- end
287
-
288
- class << self
289
- alias_method :to_time_string, :to_duration_string
290
- end
291
-
292
- #
293
- # Turns a number of seconds (integer or Float) into a hash like in :
294
- #
295
- # Rufus.to_duration_hash 0.051
296
- # # => { :ms => "51" }
297
- # Rufus.to_duration_hash 7.051
298
- # # => { :s => 7, :ms => "51" }
299
- # Rufus.to_duration_hash 0.120 + 30 * 24 * 3600 + 1
300
- # # => { :w => 4, :d => 2, :s => 1, :ms => "120" }
301
- #
302
- # This method is used by to_duration_string (to_time_string) behind
303
- # the scene.
304
- #
305
- # Options are :
306
- #
307
- # * :months, if set to true, months (M) of 30 days will be taken into
308
- # account when building up the result
309
- # * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
310
- # from the result
311
- #
312
- def Rufus.to_duration_hash (seconds, options={})
313
-
314
- h = {}
315
-
316
- if seconds.is_a?(Float)
317
- h[:ms] = (seconds % 1 * 1000).to_i
318
- seconds = seconds.to_i
319
- end
320
-
321
- if options[:drop_seconds]
322
- h.delete :ms
323
- seconds = (seconds - seconds % 60)
324
- end
325
-
326
- durations = options[:months] ? DURATIONS2M : DURATIONS2
327
-
328
- durations.each do |key, duration|
329
-
330
- count = seconds / duration
331
- seconds = seconds % duration
332
-
333
- h[key.to_sym] = count if count > 0
334
- end
335
-
336
- h
337
- end
338
-
339
- #
340
- # Ensures that a duration is a expressed as a Float instance.
341
- #
342
- # duration_to_f("10s")
343
- #
344
- # will yield 10.0
345
- #
346
- def Rufus.duration_to_f (s)
347
-
348
- return s if s.kind_of?(Float)
349
- return parse_time_string(s) if s.kind_of?(String)
350
- Float(s.to_s)
351
- end
352
-
353
- protected
354
-
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
371
-
372
- DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
373
-
374
- end
2
+ require 'rufus/scheduler/otime'
375
3
 
@@ -90,21 +90,12 @@ module Rufus
90
90
 
91
91
  time = Time.at(time) unless time.kind_of?(Time)
92
92
 
93
- return false \
94
- if no_match?(time.sec, @seconds)
95
- #if precision <= 1 and no_match?(time.sec, @seconds)
96
- return false \
97
- if no_match?(time.min, @minutes)
98
- #if precision <= 60 and no_match?(time.min, @minutes)
99
- return false \
100
- if no_match?(time.hour, @hours)
101
- return false \
102
- if no_match?(time.day, @days)
103
- return false \
104
- if no_match?(time.month, @months)
105
- return false \
106
- if no_match?(time.wday, @weekdays)
107
-
93
+ return false unless sub_match? time.sec, @seconds
94
+ return false unless sub_match? time.min, @minutes
95
+ return false unless sub_match? time.hour, @hours
96
+ return false unless sub_match? time.day, @days
97
+ return false unless sub_match? time.month, @months
98
+ return false unless sub_match? time.wday, @weekdays
108
99
  true
109
100
  end
110
101
 
@@ -142,59 +133,35 @@ module Rufus
142
133
  #
143
134
  # (Thanks to K Liu for the note and the examples)
144
135
  #
145
- def next_time (now = Time.now)
146
-
147
- #
148
- # position now to the next cron second
136
+ def next_time time=Time.now
137
+ time -= time.usec * 1e-6
138
+ time += 1
149
139
 
150
- if @seconds
151
- next_sec = @seconds.find { |s| s > now.sec } || 60 + @seconds.first
152
- now += next_sec - now.sec
153
- else
154
- now += 1
155
- end
156
-
157
- #
158
- # prepare sec jump array
159
-
160
- sjarray = nil
161
-
162
- if @seconds
163
-
164
- sjarray = []
165
-
166
- i = @seconds.index(now.sec)
167
- ii = i
168
-
169
- loop do
170
- cur = @seconds[ii]
171
- ii += 1
172
- ii = 0 if ii == @seconds.size
173
- nxt = @seconds[ii]
174
- nxt += 60 if ii == 0
175
- sjarray << (nxt - cur)
176
- break if ii == i
140
+ loop do
141
+ unless date_match? time
142
+ time += (24 - time.hour) * 3600 - time.min * 60 - time.sec
143
+ next
177
144
  end
178
145
 
179
- else
180
-
181
- sjarray = [ 1 ]
182
- end
146
+ unless sub_match? time.hour, @hours
147
+ time += (60 - time.min) * 60 - time.sec
148
+ next
149
+ end
183
150
 
184
- #
185
- # ok, seek...
151
+ unless sub_match? time.min, @minutes
152
+ time += 60 - time.sec
153
+ next
154
+ end
186
155
 
187
- i = 0
156
+ unless sub_match? time.sec, @seconds
157
+ time += 1
158
+ next
159
+ end
188
160
 
189
- loop do
190
- return now if matches?(now)
191
- now += sjarray[i]
192
- i += 1
193
- i = 0 if i == sjarray.size
194
- # danger... potentially no exit...
161
+ break
195
162
  end
196
163
 
197
- nil
164
+ time
198
165
  end
199
166
 
200
167
  private
@@ -307,15 +274,15 @@ module Rufus
307
274
  result
308
275
  end
309
276
 
310
- def no_match? (value, cron_values)
311
-
312
- return false if not cron_values
313
-
314
- cron_values.each do |v|
315
- return false if value == v # ok, it matches
316
- end
277
+ def sub_match? value, values
278
+ values.nil? || values.include?(value)
279
+ end
317
280
 
318
- true # no match found
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
319
286
  end
320
287
  end
321
288