rocketjob 5.2.0.beta1 → 5.3.1
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.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/rocket_job/batch.rb +1 -0
- data/lib/rocket_job/batch/io.rb +2 -2
- data/lib/rocket_job/batch/throttle.rb +1 -1
- data/lib/rocket_job/batch/throttle_running_workers.rb +14 -1
- data/lib/rocket_job/batch/throttle_windows.rb +72 -0
- data/lib/rocket_job/batch/worker.rb +64 -51
- data/lib/rocket_job/event.rb +0 -2
- data/lib/rocket_job/extensions/mongoid/clients/options.rb +0 -2
- data/lib/rocket_job/plugins/cron.rb +5 -12
- data/lib/rocket_job/plugins/job/throttle.rb +1 -1
- data/lib/rocket_job/plugins/job/throttle_running_jobs.rb +1 -1
- data/lib/rocket_job/plugins/processing_window.rb +7 -13
- data/lib/rocket_job/sliced/slice.rb +5 -7
- data/lib/rocket_job/version.rb +1 -1
- metadata +21 -8
- data/lib/rocket_job/plugins/rufus/cron_line.rb +0 -520
- data/lib/rocket_job/plugins/rufus/zo_time.rb +0 -524
@@ -1,524 +0,0 @@
|
|
1
|
-
#--
|
2
|
-
# Copyright (c) 2006-2017, 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
|
-
# Made in Japan.
|
23
|
-
#++
|
24
|
-
#@formatter:off
|
25
|
-
|
26
|
-
module RocketJob::Plugins::Rufus
|
27
|
-
#
|
28
|
-
# Zon{ing|ed}Time, whatever.
|
29
|
-
#
|
30
|
-
class ZoTime
|
31
|
-
|
32
|
-
attr_reader :seconds
|
33
|
-
attr_reader :zone
|
34
|
-
|
35
|
-
def initialize(s, zone)
|
36
|
-
|
37
|
-
@seconds = s.to_f
|
38
|
-
@zone = self.class.get_tzone(zone || :current)
|
39
|
-
|
40
|
-
fail ArgumentError.new(
|
41
|
-
"cannot determine timezone from #{zone.inspect}" +
|
42
|
-
" (etz:#{ENV['TZ'].inspect},tnz:#{Time.now.zone.inspect}," +
|
43
|
-
"tzid:#{defined?(TZInfo::Data).inspect})\n" +
|
44
|
-
"Try setting `ENV['TZ'] = 'Continent/City'` in your script " +
|
45
|
-
"(see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)" +
|
46
|
-
(defined?(TZInfo::Data) ? '' : " and adding 'tzinfo-data' to your gems")
|
47
|
-
) unless @zone
|
48
|
-
|
49
|
-
@time = nil # cache for #to_time result
|
50
|
-
end
|
51
|
-
|
52
|
-
def seconds=(f)
|
53
|
-
|
54
|
-
@time = nil
|
55
|
-
@seconds = f
|
56
|
-
end
|
57
|
-
|
58
|
-
def zone=(z)
|
59
|
-
|
60
|
-
@time = nil
|
61
|
-
@zone = self.class.get_tzone(zone || :current)
|
62
|
-
end
|
63
|
-
|
64
|
-
def utc
|
65
|
-
|
66
|
-
Time.utc(1970, 1, 1) + @seconds
|
67
|
-
end
|
68
|
-
|
69
|
-
# Returns a Ruby Time instance.
|
70
|
-
#
|
71
|
-
# Warning: the timezone of that Time instance will be UTC.
|
72
|
-
#
|
73
|
-
def to_time
|
74
|
-
|
75
|
-
@time ||= begin; u = utc; @zone.period_for_utc(u).to_local(u); end
|
76
|
-
end
|
77
|
-
|
78
|
-
%w[
|
79
|
-
year month day wday hour min sec usec asctime
|
80
|
-
].each do |m|
|
81
|
-
define_method(m) { to_time.send(m) }
|
82
|
-
end
|
83
|
-
def iso8601(fraction_digits=0); to_time.iso8601(fraction_digits); end
|
84
|
-
|
85
|
-
def ==(o)
|
86
|
-
|
87
|
-
o.is_a?(ZoTime) && o.seconds == @seconds && o.zone == @zone
|
88
|
-
end
|
89
|
-
#alias eq? == # FIXME see Object#== (ri)
|
90
|
-
|
91
|
-
def >(o); @seconds > _to_f(o); end
|
92
|
-
def >=(o); @seconds >= _to_f(o); end
|
93
|
-
def <(o); @seconds < _to_f(o); end
|
94
|
-
def <=(o); @seconds <= _to_f(o); end
|
95
|
-
def <=>(o); @seconds <=> _to_f(o); end
|
96
|
-
|
97
|
-
alias getutc utc
|
98
|
-
alias getgm utc
|
99
|
-
|
100
|
-
def to_i
|
101
|
-
|
102
|
-
@seconds.to_i
|
103
|
-
end
|
104
|
-
|
105
|
-
def to_f
|
106
|
-
|
107
|
-
@seconds
|
108
|
-
end
|
109
|
-
|
110
|
-
def is_dst?
|
111
|
-
|
112
|
-
@zone.period_for_utc(utc).std_offset != 0
|
113
|
-
end
|
114
|
-
alias isdst is_dst?
|
115
|
-
|
116
|
-
def utc_offset
|
117
|
-
|
118
|
-
#@zone.period_for_utc(utc).utc_offset
|
119
|
-
#@zone.period_for_utc(utc).utc_total_offset
|
120
|
-
#@zone.period_for_utc(utc).std_offset
|
121
|
-
@zone.period_for_utc(utc).utc_offset
|
122
|
-
end
|
123
|
-
|
124
|
-
def strftime(format)
|
125
|
-
|
126
|
-
format = format.gsub(/%(\/?Z|:{0,2}z)/) { |f| strfz(f) }
|
127
|
-
|
128
|
-
to_time.strftime(format)
|
129
|
-
end
|
130
|
-
|
131
|
-
def add(t); @time = nil; @seconds += t.to_f; end
|
132
|
-
def substract(t); @time = nil; @seconds -= t.to_f; end
|
133
|
-
|
134
|
-
def +(t); inc(t, 1); end
|
135
|
-
def -(t); inc(t, -1); end
|
136
|
-
|
137
|
-
WEEK_S = 7 * 24 * 3600
|
138
|
-
|
139
|
-
def monthdays
|
140
|
-
|
141
|
-
date = to_time
|
142
|
-
|
143
|
-
pos = 1
|
144
|
-
d = self.dup
|
145
|
-
|
146
|
-
loop do
|
147
|
-
d.add(-WEEK_S)
|
148
|
-
break if d.month != date.month
|
149
|
-
pos = pos + 1
|
150
|
-
end
|
151
|
-
|
152
|
-
neg = -1
|
153
|
-
d = self.dup
|
154
|
-
|
155
|
-
loop do
|
156
|
-
d.add(WEEK_S)
|
157
|
-
break if d.month != date.month
|
158
|
-
neg = neg - 1
|
159
|
-
end
|
160
|
-
|
161
|
-
[ "#{date.wday}##{pos}", "#{date.wday}##{neg}" ]
|
162
|
-
end
|
163
|
-
|
164
|
-
def to_s
|
165
|
-
|
166
|
-
strftime('%Y-%m-%d %H:%M:%S %z')
|
167
|
-
end
|
168
|
-
|
169
|
-
def to_debug_s
|
170
|
-
|
171
|
-
uo = self.utc_offset
|
172
|
-
uos = uo < 0 ? '-' : '+'
|
173
|
-
uo = uo.abs
|
174
|
-
uoh, uom = [ uo / 3600, uo % 3600 ]
|
175
|
-
|
176
|
-
[
|
177
|
-
'zt',
|
178
|
-
self.strftime('%Y-%m-%d %H:%M:%S'),
|
179
|
-
"%s%02d:%02d" % [ uos, uoh, uom ],
|
180
|
-
"dst:#{self.isdst}"
|
181
|
-
].join(' ')
|
182
|
-
end
|
183
|
-
|
184
|
-
# Debug current time by showing local time / delta / utc time
|
185
|
-
# for example: "0120-7(0820)"
|
186
|
-
#
|
187
|
-
def to_utc_comparison_s
|
188
|
-
|
189
|
-
per = @zone.period_for_utc(utc)
|
190
|
-
off = per.utc_total_offset
|
191
|
-
|
192
|
-
off = off / 3600
|
193
|
-
off = off >= 0 ? "+#{off}" : off.to_s
|
194
|
-
|
195
|
-
strftime('%H%M') + off + utc.strftime('(%H%M)')
|
196
|
-
end
|
197
|
-
|
198
|
-
def to_time_s
|
199
|
-
|
200
|
-
strftime("%H:%M:%S.#{'%06d' % usec}")
|
201
|
-
end
|
202
|
-
|
203
|
-
def self.now(zone=nil)
|
204
|
-
|
205
|
-
ZoTime.new(Time.now.to_f, zone)
|
206
|
-
end
|
207
|
-
|
208
|
-
# https://en.wikipedia.org/wiki/ISO_8601
|
209
|
-
# Postel's law applies
|
210
|
-
#
|
211
|
-
def self.extract_iso8601_zone(s)
|
212
|
-
|
213
|
-
m = s.match(
|
214
|
-
/[0-2]\d(?::?[0-6]\d(?::?[0-6]\d))?\s*([+-]\d\d(?::?\d\d)?)\s*\z/)
|
215
|
-
return nil unless m
|
216
|
-
|
217
|
-
zs = m[1].split(':')
|
218
|
-
zs << '00' if zs.length < 2
|
219
|
-
|
220
|
-
zh = zs[0].to_i.abs
|
221
|
-
|
222
|
-
return nil if zh > 24
|
223
|
-
return nil if zh == 24 && zs[1].to_i != 0
|
224
|
-
|
225
|
-
zs.join(':')
|
226
|
-
end
|
227
|
-
|
228
|
-
def self.parse(str, opts={})
|
229
|
-
|
230
|
-
if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
|
231
|
-
return ZoTime.new(t, nil)
|
232
|
-
end
|
233
|
-
|
234
|
-
#rold = RUBY_VERSION < '1.9.0'
|
235
|
-
#rold = RUBY_VERSION < '2.0.0'
|
236
|
-
|
237
|
-
begin
|
238
|
-
DateTime.parse(str)
|
239
|
-
rescue
|
240
|
-
fail ArgumentError, "no time information in #{str.inspect}"
|
241
|
-
end #if rold
|
242
|
-
#
|
243
|
-
# is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now`
|
244
|
-
|
245
|
-
zone = nil
|
246
|
-
|
247
|
-
s =
|
248
|
-
str.gsub(/\S+/) do |w|
|
249
|
-
if z = get_tzone(w)
|
250
|
-
zone ||= z
|
251
|
-
''
|
252
|
-
else
|
253
|
-
w
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
local = Time.parse(s)
|
258
|
-
izone = extract_iso8601_zone(s)
|
259
|
-
|
260
|
-
zone ||=
|
261
|
-
if s.match(/\dZ\b/)
|
262
|
-
get_tzone('Zulu')
|
263
|
-
#elsif rold && izone
|
264
|
-
elsif izone
|
265
|
-
get_tzone(izone)
|
266
|
-
elsif local.zone.nil? && izone
|
267
|
-
get_tzone(local.strftime('%:z'))
|
268
|
-
else
|
269
|
-
get_tzone(:local)
|
270
|
-
end
|
271
|
-
|
272
|
-
secs =
|
273
|
-
#if rold && izone
|
274
|
-
if izone
|
275
|
-
local.to_f
|
276
|
-
else
|
277
|
-
zone.period_for_local(local).to_utc(local).to_f
|
278
|
-
end
|
279
|
-
|
280
|
-
ZoTime.new(secs, zone)
|
281
|
-
end
|
282
|
-
|
283
|
-
def self.get_tzone(str)
|
284
|
-
|
285
|
-
return str if str.is_a?(::TZInfo::Timezone)
|
286
|
-
|
287
|
-
# discard quickly when it's certainly not a timezone
|
288
|
-
|
289
|
-
return nil if str == nil
|
290
|
-
return nil if str == '*'
|
291
|
-
|
292
|
-
ostr = str
|
293
|
-
str = :current if str == :local
|
294
|
-
|
295
|
-
# use Rails' zone by default if Rails is present
|
296
|
-
|
297
|
-
return Time.zone.tzinfo if (
|
298
|
-
ENV['TZ'].nil? && str == :current &&
|
299
|
-
Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo)
|
300
|
-
)
|
301
|
-
|
302
|
-
# ok, it's a timezone then
|
303
|
-
|
304
|
-
str = ENV['TZ'] || Time.now.zone if str == :current
|
305
|
-
|
306
|
-
# utc_offset
|
307
|
-
|
308
|
-
if str.is_a?(Numeric)
|
309
|
-
i = str.to_i
|
310
|
-
sn = i < 0 ? '-' : '+'; i = i.abs
|
311
|
-
hr = i / 3600; mn = i % 3600; sc = i % 60
|
312
|
-
str = (sc > 0 ? "%s%02d:%02d:%02d" : "%s%02d:%02d") % [ sn, hr, mn, sc ]
|
313
|
-
end
|
314
|
-
|
315
|
-
return nil if str.index('#')
|
316
|
-
# counters "sun#2", etc... On OSX would go all the way to true
|
317
|
-
|
318
|
-
# vanilla time zones
|
319
|
-
|
320
|
-
z = (::TZInfo::Timezone.get(str) rescue nil)
|
321
|
-
return z if z
|
322
|
-
|
323
|
-
# time zone abbreviations
|
324
|
-
|
325
|
-
if str.match(/\A[A-Z0-9-]{3,6}\z/)
|
326
|
-
|
327
|
-
toff = Time.now.utc_offset
|
328
|
-
toff = nil if str != Time.now.zone
|
329
|
-
|
330
|
-
twin = Time.utc(Time.now.year, 1, 1) # winter
|
331
|
-
tsum = Time.utc(Time.now.year, 7, 1) # summer
|
332
|
-
|
333
|
-
z =
|
334
|
-
::TZInfo::Timezone.all.find do |tz|
|
335
|
-
|
336
|
-
pwin = tz.period_for_utc(twin)
|
337
|
-
psum = tz.period_for_utc(tsum)
|
338
|
-
|
339
|
-
if toff
|
340
|
-
(pwin.abbreviation.to_s == str && pwin.utc_offset == toff) ||
|
341
|
-
(psum.abbreviation.to_s == str && psum.utc_offset == toff)
|
342
|
-
else
|
343
|
-
# returns the first tz with the given abbreviation, almost useless
|
344
|
-
# favour fully named zones...
|
345
|
-
pwin.abbreviation.to_s == str ||
|
346
|
-
psum.abbreviation.to_s == str
|
347
|
-
end
|
348
|
-
end
|
349
|
-
return z if z
|
350
|
-
end
|
351
|
-
|
352
|
-
# some time zone aliases
|
353
|
-
|
354
|
-
return ::TZInfo::Timezone.get('Zulu') if %w[ Z ].include?(str)
|
355
|
-
|
356
|
-
# custom timezones, no DST, just an offset, like "+08:00" or "-01:30"
|
357
|
-
|
358
|
-
tz = (@custom_tz_cache ||= {})[str]
|
359
|
-
return tz if tz
|
360
|
-
|
361
|
-
if m = str.match(/\A([+-][0-1][0-9]):?([0-5][0-9])\z/)
|
362
|
-
|
363
|
-
hr = m[1].to_i
|
364
|
-
mn = m[2].to_i
|
365
|
-
|
366
|
-
hr = nil if hr.abs > 11
|
367
|
-
hr = nil if mn > 59
|
368
|
-
mn = -mn if hr && hr < 0
|
369
|
-
|
370
|
-
return (
|
371
|
-
@custom_tz_cache[str] =
|
372
|
-
begin
|
373
|
-
tzi = TZInfo::TransitionDataTimezoneInfo.new(str)
|
374
|
-
tzi.offset(str, hr * 3600 + mn * 60, 0, str)
|
375
|
-
tzi.create_timezone
|
376
|
-
end
|
377
|
-
) if hr
|
378
|
-
end
|
379
|
-
|
380
|
-
# try with ENV['TZ']
|
381
|
-
|
382
|
-
z = ostr == :current && (::TZInfo::Timezone.get(ENV['TZ']) rescue nil)
|
383
|
-
return z if z
|
384
|
-
|
385
|
-
# ask the system
|
386
|
-
|
387
|
-
z = ostr == :current && (debian_tz || centos_tz || osx_tz)
|
388
|
-
return z if z
|
389
|
-
|
390
|
-
# so it's not a timezone.
|
391
|
-
|
392
|
-
nil
|
393
|
-
end
|
394
|
-
|
395
|
-
def self.debian_tz
|
396
|
-
|
397
|
-
path = '/etc/timezone'
|
398
|
-
|
399
|
-
File.exist?(path) &&
|
400
|
-
(::TZInfo::Timezone.get(File.read(path).strip) rescue nil)
|
401
|
-
end
|
402
|
-
|
403
|
-
def self.centos_tz
|
404
|
-
|
405
|
-
path = '/etc/sysconfig/clock'
|
406
|
-
|
407
|
-
File.open(path, 'rb') do |f|
|
408
|
-
until f.eof?
|
409
|
-
m = f.readline.match(/ZONE="([^"]+)"/)
|
410
|
-
return (::TZInfo::Timezone.get(m[1]) rescue nil) if m
|
411
|
-
end
|
412
|
-
end if File.exist?(path)
|
413
|
-
|
414
|
-
nil
|
415
|
-
end
|
416
|
-
|
417
|
-
def self.osx_tz
|
418
|
-
|
419
|
-
path = '/etc/localtime'
|
420
|
-
|
421
|
-
return nil unless File.exist?(path)
|
422
|
-
|
423
|
-
::TZInfo::Timezone.get(
|
424
|
-
File.readlink(path).split('/')[4..-1].join('/')
|
425
|
-
) rescue nil
|
426
|
-
end
|
427
|
-
|
428
|
-
def self.local_tzone
|
429
|
-
|
430
|
-
get_tzone(:local)
|
431
|
-
end
|
432
|
-
|
433
|
-
def self.make(o)
|
434
|
-
|
435
|
-
zt =
|
436
|
-
case o
|
437
|
-
when Time
|
438
|
-
ZoTime.new(o.to_f, o.zone)
|
439
|
-
when Date
|
440
|
-
t =
|
441
|
-
o.respond_to?(:to_time) ?
|
442
|
-
o.to_time :
|
443
|
-
Time.parse(o.strftime('%Y-%m-%d %H:%M:%S'))
|
444
|
-
ZoTime.new(t.to_f, t.zone)
|
445
|
-
when String
|
446
|
-
Rufus::Scheduler.parse_in(o, :no_error => true) || self.parse(o)
|
447
|
-
else
|
448
|
-
o
|
449
|
-
end
|
450
|
-
|
451
|
-
zt = ZoTime.new(Time.now.to_f + zt, nil) if zt.is_a?(Numeric)
|
452
|
-
|
453
|
-
fail ArgumentError.new(
|
454
|
-
"cannot turn #{o.inspect} to a ZoTime instance"
|
455
|
-
) unless zt.is_a?(ZoTime)
|
456
|
-
|
457
|
-
zt
|
458
|
-
end
|
459
|
-
|
460
|
-
# def in_zone(&block)
|
461
|
-
#
|
462
|
-
# current_timezone = ENV['TZ']
|
463
|
-
# ENV['TZ'] = @zone
|
464
|
-
#
|
465
|
-
# block.call
|
466
|
-
#
|
467
|
-
# ensure
|
468
|
-
#
|
469
|
-
# ENV['TZ'] = current_timezone
|
470
|
-
# end
|
471
|
-
|
472
|
-
protected
|
473
|
-
|
474
|
-
def inc(t, dir)
|
475
|
-
|
476
|
-
if t.is_a?(Numeric)
|
477
|
-
nt = self.dup
|
478
|
-
nt.seconds += dir * t.to_f
|
479
|
-
nt
|
480
|
-
elsif t.respond_to?(:to_f)
|
481
|
-
@seconds + dir * t.to_f
|
482
|
-
else
|
483
|
-
fail ArgumentError.new(
|
484
|
-
"cannot call ZoTime #- or #+ with arg of class #{t.class}")
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
def _to_f(o)
|
489
|
-
|
490
|
-
fail ArgumentError(
|
491
|
-
"comparison of ZoTime with #{o.inspect} failed"
|
492
|
-
) unless o.is_a?(ZoTime) || o.is_a?(Time)
|
493
|
-
|
494
|
-
o.to_f
|
495
|
-
end
|
496
|
-
|
497
|
-
def strfz(code)
|
498
|
-
|
499
|
-
return @zone.name if code == '%/Z'
|
500
|
-
|
501
|
-
per = @zone.period_for_utc(utc)
|
502
|
-
|
503
|
-
return per.abbreviation.to_s if code == '%Z'
|
504
|
-
|
505
|
-
off = per.utc_total_offset
|
506
|
-
#
|
507
|
-
sn = off < 0 ? '-' : '+'; off = off.abs
|
508
|
-
hr = off / 3600
|
509
|
-
mn = (off % 3600) / 60
|
510
|
-
sc = 0
|
511
|
-
|
512
|
-
fmt =
|
513
|
-
if code == '%z'
|
514
|
-
"%s%02d%02d"
|
515
|
-
elsif code == '%:z'
|
516
|
-
"%s%02d:%02d"
|
517
|
-
else
|
518
|
-
"%s%02d:%02d:%02d"
|
519
|
-
end
|
520
|
-
|
521
|
-
fmt % [ sn, hr, mn, sc ]
|
522
|
-
end
|
523
|
-
end
|
524
|
-
end
|