rufus-scheduler 2.0.24 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -1,363 +0,0 @@
1
- #--
2
- # Copyright (c) 2005-2013, 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
- #
22
- # Hecho en Costa Rica
23
- #++
24
-
25
-
26
- require 'date'
27
-
28
-
29
- module Rufus
30
-
31
- #--
32
- #
33
- # keeping that as a note.
34
- #
35
- #require 'tzinfo'
36
- #def time_zone(time)
37
- # offset = time.utc_offset / 3600
38
- # offset = offset < 0 ? offset.to_s : "+#{offset}"
39
- # TZInfo::Timezone.get("Etc/GMT#{offset}")
40
- #end
41
- #def timeshift(time, tz)
42
- # tz = TZInfo::Timezone.get(tz) unless tz.is_a?(TZInfo::Timezone)
43
- # t = tz.utc_to_local(time.getutc)
44
- # Time.parse(t.to_s[0..-5])
45
- #end
46
- #++
47
-
48
- # Returns the current time as an ISO date string
49
- #
50
- def Rufus.now
51
-
52
- to_iso8601_date(Time.new)
53
- end
54
-
55
- # As the name implies.
56
- #
57
- def Rufus.to_iso8601_date(date)
58
-
59
- date = case date
60
- when Date then date
61
- when Float then to_datetime(Time.at(date))
62
- when Time then to_datetime(date)
63
- else DateTime.parse(date)
64
- end
65
-
66
- s = date.to_s # this is costly
67
- s[10] = ' '
68
-
69
- s
70
- end
71
-
72
- # the old method we used to generate our ISO datetime strings
73
- #
74
- def Rufus.time_to_iso8601_date(time)
75
-
76
- s = time.getutc.strftime(TIME_FORMAT)
77
- o = time.utc_offset / 3600
78
- o = "#{o}00"
79
- o = "0#{o}" if o.length < 4
80
- o = "+#{o}" unless o[0..1] == '-'
81
-
82
- "#{s} #{o}"
83
- end
84
-
85
- # Returns a Ruby time
86
- #
87
- def Rufus.to_ruby_time(sdate)
88
-
89
- DateTime.parse(sdate)
90
- end
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
- # Turns a string like '1m10s' into a float like '70.0', more formally,
100
- # turns a time duration expressed as a string into a Float instance
101
- # (millisecond count).
102
- #
103
- # w -> week
104
- # d -> day
105
- # h -> hour
106
- # m -> minute
107
- # s -> second
108
- # M -> month
109
- # y -> year
110
- # 'nada' -> millisecond
111
- #
112
- # Some examples :
113
- #
114
- # Rufus.parse_time_string "0.5" # => 0.5
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
- # Note will call #to_s on the input "string", so anything that is a String
122
- # or responds to #to_s will be OK.
123
- #
124
- def self.parse_time_string(string)
125
-
126
- string = string.to_s
127
-
128
- return 0.0 if string == ''
129
-
130
- m = string.match(/^(-?)([\d\.#{DURATION_LETTERS}]+)$/)
131
-
132
- raise ArgumentError.new("cannot parse '#{string}'") unless m
133
-
134
- mod = m[1] == '-' ? -1.0 : 1.0
135
- val = 0.0
136
-
137
- s = m[2]
138
-
139
- while s.length > 0
140
- m = nil
141
- if m = s.match(/^(\d+|\d+\.\d*|\d*\.\d+)([#{DURATION_LETTERS}])(.*)$/)
142
- val += m[1].to_f * DURATIONS[m[2]]
143
- elsif s.match(/^\d+$/)
144
- val += s.to_i / 1000.0
145
- elsif s.match(/^\d*\.\d*$/)
146
- val += s.to_f
147
- else
148
- raise ArgumentError.new("cannot parse '#{string}' (especially '#{s}')")
149
- end
150
- break unless m && m[3]
151
- s = m[3]
152
- end
153
-
154
- mod * val
155
- end
156
-
157
- class << self
158
- alias_method :parse_duration_string, :parse_time_string
159
- end
160
-
161
- #--
162
- # conversion methods between Date[Time] and Time
163
- #++
164
-
165
- #--
166
- # Ruby Cookbook 1st edition p.111
167
- # http://www.oreilly.com/catalog/rubyckbk/
168
- # a must
169
- #++
170
-
171
- # Converts a Time instance to a DateTime one
172
- #
173
- def Rufus.to_datetime(time)
174
-
175
- s = time.sec + Rational(time.usec, 10**6)
176
- o = Rational(time.utc_offset, 3600 * 24)
177
-
178
- begin
179
-
180
- DateTime.new(time.year, time.month, time.day, time.hour, time.min, s, o)
181
-
182
- rescue Exception => e
183
-
184
- DateTime.new(
185
- time.year,
186
- time.month,
187
- time.day,
188
- time.hour,
189
- time.min,
190
- time.sec,
191
- time.utc_offset)
192
- end
193
- end
194
-
195
- def Rufus.to_gm_time(dtime)
196
-
197
- to_ttime(dtime.new_offset, :gm)
198
- end
199
-
200
- def Rufus.to_local_time(dtime)
201
-
202
- to_ttime(dtime.new_offset(DateTime.now.offset - offset), :local)
203
- end
204
-
205
- def Rufus.to_ttime(d, method)
206
-
207
- usec = (d.sec_fraction * 3600 * 24 * (10**6)).to_i
208
- Time.send(method, d.year, d.month, d.day, d.hour, d.min, d.sec, usec)
209
- end
210
-
211
- # Turns a number of seconds into a a time string
212
- #
213
- # Rufus.to_duration_string 0 # => '0s'
214
- # Rufus.to_duration_string 60 # => '1m'
215
- # Rufus.to_duration_string 3661 # => '1h1m1s'
216
- # Rufus.to_duration_string 7 * 24 * 3600 # => '1w'
217
- # Rufus.to_duration_string 30 * 24 * 3600 + 1 # => "4w2d1s"
218
- #
219
- # It goes from seconds to the year. Months are not counted (as they
220
- # are of variable length). Weeks are counted.
221
- #
222
- # For 30 days months to be counted, the second parameter of this
223
- # method can be set to true.
224
- #
225
- # Rufus.to_time_string 30 * 24 * 3600 + 1, true # => "1M1s"
226
- #
227
- # (to_time_string is an alias for to_duration_string)
228
- #
229
- # If a Float value is passed, milliseconds will be displayed without
230
- # 'marker'
231
- #
232
- # Rufus.to_duration_string 0.051 # =>"51"
233
- # Rufus.to_duration_string 7.051 # =>"7s51"
234
- # Rufus.to_duration_string 0.120 + 30 * 24 * 3600 + 1 # =>"4w2d1s120"
235
- #
236
- # (this behaviour mirrors the one found for parse_time_string()).
237
- #
238
- # Options are :
239
- #
240
- # * :months, if set to true, months (M) of 30 days will be taken into
241
- # account when building up the result
242
- # * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
243
- # from the result
244
- #
245
- def Rufus.to_duration_string(seconds, options={})
246
-
247
- return (options[:drop_seconds] ? '0m' : '0s') if seconds <= 0
248
-
249
- h = to_duration_hash(seconds, options)
250
-
251
- s = DU_KEYS.inject('') { |r, key|
252
- count = h[key]
253
- count = nil if count == 0
254
- r << "#{count}#{key}" if count
255
- r
256
- }
257
-
258
- ms = h[:ms]
259
- s << ms.to_s if ms
260
-
261
- s
262
- end
263
-
264
- class << self
265
- alias_method :to_time_string, :to_duration_string
266
- end
267
-
268
- # Turns a number of seconds (integer or Float) into a hash like in :
269
- #
270
- # Rufus.to_duration_hash 0.051
271
- # # => { :ms => "51" }
272
- # Rufus.to_duration_hash 7.051
273
- # # => { :s => 7, :ms => "51" }
274
- # Rufus.to_duration_hash 0.120 + 30 * 24 * 3600 + 1
275
- # # => { :w => 4, :d => 2, :s => 1, :ms => "120" }
276
- #
277
- # This method is used by to_duration_string (to_time_string) behind
278
- # the scene.
279
- #
280
- # Options are :
281
- #
282
- # * :months, if set to true, months (M) of 30 days will be taken into
283
- # account when building up the result
284
- # * :drop_seconds, if set to true, seconds and milliseconds will be trimmed
285
- # from the result
286
- #
287
- def Rufus.to_duration_hash(seconds, options={})
288
-
289
- h = {}
290
-
291
- if seconds.is_a?(Float)
292
- h[:ms] = (seconds % 1 * 1000).to_i
293
- seconds = seconds.to_i
294
- end
295
-
296
- if options[:drop_seconds]
297
- h.delete(:ms)
298
- seconds = (seconds - seconds % 60)
299
- end
300
-
301
- durations = options[:months] ? DURATIONS2M : DURATIONS2
302
-
303
- durations.each do |key, duration|
304
-
305
- count = seconds / duration
306
- seconds = seconds % duration
307
-
308
- h[key.to_sym] = count if count > 0
309
- end
310
-
311
- h
312
- end
313
-
314
- # Ensures that a duration is a expressed as a Float instance.
315
- #
316
- # duration_to_f("10s")
317
- #
318
- # will yield 10.0
319
- #
320
- def Rufus.duration_to_f(s)
321
-
322
- return s if s.kind_of?(Float)
323
- return parse_time_string(s) if s.kind_of?(String)
324
- Float(s.to_s)
325
- end
326
-
327
- # Ensures an 'at' value is translated to a float
328
- # (to be compared with the float coming from time.to_f)
329
- #
330
- def Rufus.at_to_f(at)
331
-
332
- # TODO : use chronic if present
333
-
334
- at = to_ruby_time(at) if at.is_a?(String)
335
- at = to_gm_time(at) if at.is_a?(DateTime)
336
- #at = at.to_f if at.is_a?(Time)
337
- at = at.to_f if at.respond_to?(:to_f)
338
-
339
- raise ArgumentError.new(
340
- "cannot determine 'at' time from : #{at.inspect}"
341
- ) unless at.is_a?(Float)
342
-
343
- at
344
- end
345
-
346
- DURATIONS2M = [
347
- [ 'y', 365 * 24 * 3600 ],
348
- [ 'M', 30 * 24 * 3600 ],
349
- [ 'w', 7 * 24 * 3600 ],
350
- [ 'd', 24 * 3600 ],
351
- [ 'h', 3600 ],
352
- [ 'm', 60 ],
353
- [ 's', 1 ]
354
- ]
355
- DURATIONS2 = DURATIONS2M.dup
356
- DURATIONS2.delete_at(1)
357
-
358
- DURATIONS = DURATIONS2M.inject({}) { |r, (k, v)| r[k] = v; r }
359
- DURATION_LETTERS = DURATIONS.keys.join
360
-
361
- DU_KEYS = DURATIONS2M.collect { |k, v| k.to_sym }
362
- end
363
-