rufus-scheduler 2.0.24 → 3.1.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 (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
-