rocketjob 3.0.0.rc5 → 3.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ba208764fdc107e2344875ae2370fcd382f13455
4
- data.tar.gz: 3e048ff46edb4bc5648659b42f2d5177d67ce8f1
3
+ metadata.gz: 665d894a78de154892a8c53e03f2a2a81f6230f9
4
+ data.tar.gz: d89dba90f39ef98f7205366b166a45d928fb84db
5
5
  SHA512:
6
- metadata.gz: 2feee5c761e3b7f5bc219f709547bc0356594e0c1aa2a568ac672b38bc22133e74adfd2fdb8f82249736ab68a1663989fbfaeb1787ec8f2495ac4f9f5d628050
7
- data.tar.gz: fba78d1d97e122a79a0187d8e42518e421f35fe3fa9db3cf9e7faf297fb941bcf8060ca65970ab912842dcae5d727f719d6a03f0e53583d51bf8daf2a46e1fac
6
+ metadata.gz: c275f0ca475518de2acddce890b924312e8e40e5f04f74e2f4c8a235235723c5b1d3a322d0c10dd29d512f3d2f492b6c52d917b8a491185a18a61634ecfde174
7
+ data.tar.gz: 6f368bdd55d728530252d30d16a34b0b215caaa4cbe1a199b3aa1d369a48044cbd90642e2bec55fa039238897401a5223f67c56bbe7d02d98adea63e44f2b09e
@@ -32,6 +32,9 @@ module RocketJob
32
32
  rails? ? boot_rails : boot_standalone
33
33
  write_pidfile
34
34
 
35
+ # In case Rails did not load the Mongoid Config
36
+ RocketJob::Config.load!(environment, mongo_config, symmetric_encryption_config) if Mongoid::Config.clients.empty?
37
+
35
38
  opts = {}
36
39
  opts[:name] = name if name
37
40
  opts[:max_workers] = workers if workers
@@ -55,3 +55,18 @@ module AASM
55
55
  end
56
56
  end
57
57
 
58
+ # Patch to try and make AASM threadsafe
59
+ AASM::StateMachineStore
60
+ module AASM
61
+ class StateMachineStore
62
+ @stores = Concurrent::Map.new
63
+
64
+ def self.stores
65
+ @stores
66
+ end
67
+
68
+ def initialize
69
+ @machines = Concurrent::Map.new
70
+ end
71
+ end
72
+ end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2017, 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
@@ -32,9 +32,15 @@ module RocketJob::Plugins::Rufus
32
32
  #
33
33
  class CronLine
34
34
 
35
+ # The max number of years in the future or the past before giving up
36
+ # searching for #next_time or #previous_time respectively
37
+ #
38
+ NEXT_TIME_MAX_YEARS = 14
39
+
35
40
  # The string used for creating this cronline instance.
36
41
  #
37
42
  attr_reader :original
43
+ attr_reader :original_timezone
38
44
 
39
45
  attr_reader :seconds
40
46
  attr_reader :minutes
@@ -52,10 +58,15 @@ module RocketJob::Plugins::Rufus
52
58
  ) unless line.is_a?(String)
53
59
 
54
60
  @original = line
61
+ @original_timezone = nil
55
62
 
56
63
  items = line.split
57
64
 
58
- @timezone = items.pop if ZoTime.is_timezone?(items.last)
65
+ if @timezone = RocketJob::Plugins::Rufus::ZoTime.get_tzone(items.last)
66
+ @original_timezone = items.pop
67
+ else
68
+ @timezone = RocketJob::Plugins::Rufus::ZoTime.get_tzone(:current)
69
+ end
59
70
 
60
71
  fail ArgumentError.new(
61
72
  "not a valid cronline : '#{line}'"
@@ -76,18 +87,26 @@ module RocketJob::Plugins::Rufus
76
87
  "invalid cronline: '#{line}'"
77
88
  ) if es && es.find { |e| ! e.is_a?(Fixnum) }
78
89
  end
90
+
91
+ if @days && @days.include?(0) # gh-221
92
+
93
+ fail ArgumentError.new('invalid day 0 in cronline')
94
+ end
79
95
  end
80
96
 
81
97
  # Returns true if the given time matches this cron line.
82
98
  #
83
99
  def matches?(time)
84
100
 
85
- time = ZoTime.new(time.to_f, @timezone || ENV['TZ']).time
101
+ # FIXME Don't create a new ZoTime if time is already a ZoTime in same
102
+ # zone ...
103
+ # Wait, this seems only used in specs...
104
+ t = ZoTime.new(time.to_f, @timezone)
86
105
 
87
- return false unless sub_match?(time, :sec, @seconds)
88
- return false unless sub_match?(time, :min, @minutes)
89
- return false unless sub_match?(time, :hour, @hours)
90
- return false unless date_match?(time)
106
+ return false unless sub_match?(t, :sec, @seconds)
107
+ return false unless sub_match?(t, :min, @minutes)
108
+ return false unless sub_match?(t, :hour, @hours)
109
+ return false unless date_match?(t)
91
110
  true
92
111
  end
93
112
 
@@ -118,78 +137,90 @@ module RocketJob::Plugins::Rufus
118
137
  #
119
138
  # (Thanks to K Liu for the note and the examples)
120
139
  #
121
- def next_time(from=Time.now)
140
+ def next_time(from=ZoTime.now)
122
141
 
123
- time = nil
124
- zotime = ZoTime.new(from.to_i + 1, @timezone || ENV['TZ'])
142
+ nt = nil
143
+ zt = ZoTime.new(from.to_i + 1, @timezone)
144
+ maxy = from.year + NEXT_TIME_MAX_YEARS
125
145
 
126
146
  loop do
127
147
 
128
- time = zotime.time
148
+ nt = zt.dup
149
+
150
+ fail RangeError.new(
151
+ "failed to reach occurrence within " +
152
+ "#{NEXT_TIME_MAX_YEARS} years for '#{original}'"
153
+ ) if nt.year > maxy
129
154
 
130
- unless date_match?(time)
131
- zotime.add((24 - time.hour) * 3600 - time.min * 60 - time.sec)
155
+ unless date_match?(nt)
156
+ zt.add((24 - nt.hour) * 3600 - nt.min * 60 - nt.sec)
132
157
  next
133
158
  end
134
- unless sub_match?(time, :hour, @hours)
135
- zotime.add((60 - time.min) * 60 - time.sec)
159
+ unless sub_match?(nt, :hour, @hours)
160
+ zt.add((60 - nt.min) * 60 - nt.sec)
136
161
  next
137
162
  end
138
- unless sub_match?(time, :min, @minutes)
139
- zotime.add(60 - time.sec)
163
+ unless sub_match?(nt, :min, @minutes)
164
+ zt.add(60 - nt.sec)
140
165
  next
141
166
  end
142
- unless sub_match?(time, :sec, @seconds)
143
- zotime.add(next_second(time))
167
+ unless sub_match?(nt, :sec, @seconds)
168
+ zt.add(next_second(nt))
144
169
  next
145
170
  end
146
171
 
147
172
  break
148
173
  end
149
174
 
150
- time
175
+ nt
151
176
  end
152
177
 
153
178
  # Returns the previous time the cronline matched. It's like next_time, but
154
179
  # for the past.
155
180
  #
156
- def previous_time(from=Time.now)
181
+ def previous_time(from=ZoTime.now)
157
182
 
158
- time = nil
159
- zotime = ZoTime.new(from.to_i - 1, @timezone || ENV['TZ'])
183
+ pt = nil
184
+ zt = ZoTime.new(from.to_i - 1, @timezone)
185
+ miny = from.year - NEXT_TIME_MAX_YEARS
160
186
 
161
187
  loop do
162
188
 
163
- time = zotime.time
189
+ pt = zt.dup
190
+
191
+ fail RangeError.new(
192
+ "failed to reach occurrence within " +
193
+ "#{NEXT_TIME_MAX_YEARS} years for '#{original}'"
194
+ ) if pt.year < miny
164
195
 
165
- unless date_match?(time)
166
- zotime.substract(time.hour * 3600 + time.min * 60 + time.sec + 1)
196
+ unless date_match?(pt)
197
+ zt.substract(pt.hour * 3600 + pt.min * 60 + pt.sec + 1)
167
198
  next
168
199
  end
169
- unless sub_match?(time, :hour, @hours)
170
- zotime.substract(time.min * 60 + time.sec + 1)
200
+ unless sub_match?(pt, :hour, @hours)
201
+ zt.substract(pt.min * 60 + pt.sec + 1)
171
202
  next
172
203
  end
173
- unless sub_match?(time, :min, @minutes)
174
- zotime.substract(time.sec + 1)
204
+ unless sub_match?(pt, :min, @minutes)
205
+ zt.substract(pt.sec + 1)
175
206
  next
176
207
  end
177
- unless sub_match?(time, :sec, @seconds)
178
- zotime.substract(prev_second(time))
208
+ unless sub_match?(pt, :sec, @seconds)
209
+ zt.substract(prev_second(pt))
179
210
  next
180
211
  end
181
212
 
182
213
  break
183
214
  end
184
215
 
185
- time
216
+ pt
186
217
  end
187
218
 
188
219
  # Returns an array of 6 arrays (seconds, minutes, hours, days,
189
220
  # months, weekdays).
190
- # This method is used by the cronline unit tests.
221
+ # This method is mostly used by the cronline specs.
191
222
  #
192
- def to_array
223
+ def to_a
193
224
 
194
225
  [
195
226
  toa(@seconds),
@@ -199,9 +230,10 @@ module RocketJob::Plugins::Rufus
199
230
  toa(@months),
200
231
  toa(@weekdays),
201
232
  toa(@monthdays),
202
- @timezone
233
+ @timezone.name
203
234
  ]
204
235
  end
236
+ alias to_array to_a
205
237
 
206
238
  # Returns a quickly computed approximation of the frequency for this
207
239
  # cron line.
@@ -261,8 +293,10 @@ module RocketJob::Plugins::Rufus
261
293
  t1 = next_time(t0)
262
294
  d = t1 - t0
263
295
  delta = d if d < delta
264
-
265
- break if @months == nil && t1.month == 2
296
+ break if @months.nil? && t1.month == 2
297
+ break if @months.nil? && @days.nil? && t1.day == 2
298
+ break if @months.nil? && @days.nil? && @hours.nil? && t1.hour == 1
299
+ break if @months.nil? && @days.nil? && @hours.nil? && @minutes.nil? && t1.min == 1
266
300
  break if t1.year >= 2001
267
301
 
268
302
  t0 = t1
@@ -312,39 +346,38 @@ module RocketJob::Plugins::Rufus
312
346
 
313
347
  WEEKDAYS = %w[ sun mon tue wed thu fri sat ]
314
348
  DAY_S = 24 * 3600
315
- WEEK_S = 7 * DAY_S
316
349
 
317
350
  def parse_weekdays(item)
318
351
 
319
352
  return nil if item == '*'
320
353
 
321
- items = item.downcase.split(',')
322
-
323
354
  weekdays = nil
324
355
  monthdays = nil
325
356
 
326
- items.each do |it|
357
+ item.downcase.split(',').each do |it|
327
358
 
328
- if m = it.match(/^(.+)#(l|-?[12345])$/)
359
+ WEEKDAYS.each_with_index { |a, i| it.gsub!(/#{a}/, i.to_s) }
360
+
361
+ it = it.gsub(/([^#])l/, '\1#-1')
362
+ # "5L" == "5#-1" == the last Friday
363
+
364
+ if m = it.match(/\A(.+)#(l|-?[12345])\z/)
329
365
 
330
366
  fail ArgumentError.new(
331
367
  "ranges are not supported for monthdays (#{it})"
332
368
  ) if m[1].index('-')
333
369
 
334
- expr = it.gsub(/#l/, '#-1')
370
+ it = it.gsub(/#l/, '#-1')
335
371
 
336
- (monthdays ||= []) << expr
372
+ (monthdays ||= []) << it
337
373
 
338
374
  else
339
375
 
340
- expr = it.dup
341
- WEEKDAYS.each_with_index { |a, i| expr.gsub!(/#{a}/, i.to_s) }
342
-
343
376
  fail ArgumentError.new(
344
- "invalid weekday expression (#{it})"
345
- ) if expr !~ /^0*[0-7](-0*[0-7])?$/
377
+ "invalid weekday expression (#{item})"
378
+ ) if it !~ /\A0*[0-7](-0*[0-7])?\z/
346
379
 
347
- its = expr.index('-') ? parse_range(expr, 0, 7) : [ Integer(expr) ]
380
+ its = it.index('-') ? parse_range(it, 0, 7) : [ Integer(it) ]
348
381
  its = its.collect { |i| i == 7 ? 0 : i }
349
382
 
350
383
  (weekdays ||= []).concat(its)
@@ -371,7 +404,7 @@ module RocketJob::Plugins::Rufus
371
404
  Set.new(r)
372
405
  end
373
406
 
374
- RANGE_REGEX = /^(\*|-?\d{1,2})(?:-(-?\d{1,2}))?(?:\/(\d{1,2}))?$/
407
+ RANGE_REGEX = /\A(\*|-?\d{1,2})(?:-(-?\d{1,2}))?(?:\/(\d{1,2}))?\z/
375
408
 
376
409
  def parse_range(item, min, max)
377
410
 
@@ -409,6 +442,10 @@ module RocketJob::Plugins::Rufus
409
442
  "#{item.inspect} is not in range #{min}..#{max}"
410
443
  ) if sta < min || edn > max
411
444
 
445
+ fail ArgumentError.new(
446
+ "#{item.inspect} increment must be greater than zero"
447
+ ) if inc == 0
448
+
412
449
  r = []
413
450
  val = sta
414
451
 
@@ -425,12 +462,14 @@ module RocketJob::Plugins::Rufus
425
462
  r.uniq
426
463
  end
427
464
 
465
+ # FIXME: Eventually split into day_match?, hour_match? and monthdays_match?o
466
+ #
428
467
  def sub_match?(time, accessor, values)
429
468
 
430
- value = time.send(accessor)
431
-
432
469
  return true if values.nil?
433
470
 
471
+ value = time.send(accessor)
472
+
434
473
  if accessor == :day
435
474
 
436
475
  values.each do |v|
@@ -444,48 +483,37 @@ module RocketJob::Plugins::Rufus
444
483
  return true if value == 0 && values.include?(24)
445
484
  end
446
485
 
447
- values.include?(value)
448
- end
449
-
450
- def monthday_match?(date, values)
451
-
452
- return true if values.nil?
486
+ if accessor == :monthdays
453
487
 
454
- today_values = monthdays(date)
455
-
456
- (today_values & values).any?
457
- end
458
-
459
- def date_match?(date)
488
+ return true if (values & value).any?
489
+ end
460
490
 
461
- return false unless sub_match?(date, :day, @days)
462
- return false unless sub_match?(date, :month, @months)
463
- return false unless sub_match?(date, :wday, @weekdays)
464
- return false unless monthday_match?(date, @monthdays)
465
- true
491
+ values.include?(value)
466
492
  end
467
493
 
468
- def monthdays(date)
494
+ # def monthday_match?(zt, values)
495
+ #
496
+ # return true if values.nil?
497
+ #
498
+ # today_values = monthdays(zt)
499
+ #
500
+ # (today_values & values).any?
501
+ # end
469
502
 
470
- pos = 1
471
- d = date.dup
503
+ def date_match?(zt)
472
504
 
473
- loop do
474
- d = d - WEEK_S
475
- break if d.month != date.month
476
- pos = pos + 1
477
- end
505
+ return false unless sub_match?(zt, :day, @days)
506
+ return false unless sub_match?(zt, :month, @months)
478
507
 
479
- neg = -1
480
- d = date.dup
508
+ return true if (
509
+ (@weekdays && @monthdays) &&
510
+ (sub_match?(zt, :wday, @weekdays) ||
511
+ sub_match?(zt, :monthdays, @monthdays)))
481
512
 
482
- loop do
483
- d = d + WEEK_S
484
- break if d.month != date.month
485
- neg = neg - 1
486
- end
513
+ return false unless sub_match?(zt, :wday, @weekdays)
514
+ return false unless sub_match?(zt, :monthdays, @monthdays)
487
515
 
488
- [ "#{WEEKDAYS[date.wday]}##{pos}", "#{WEEKDAYS[date.wday]}##{neg}" ]
516
+ true
489
517
  end
490
518
  end
491
519
  end
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2017, 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
@@ -23,186 +23,79 @@
23
23
  #++
24
24
 
25
25
  module RocketJob::Plugins::Rufus
26
-
27
- TIMEZONES = %w[
28
- GB NZ UCT EET CET PRC ROC WET GMT EST ROK UTC MST HST MET Zulu Cuba Iran W-SU
29
- Eire GMT0 Libya Japan Egypt GMT+0 GMT-0 Israel Poland Navajo Turkey GB-Eire
30
- Iceland PST8PDT Etc/UCT CST6CDT NZ-CHAT MST7MDT Jamaica EST5EDT Etc/GMT Etc/UTC
31
- US/Samoa Etc/GMT0 Portugal Hongkong Etc/Zulu Singapore Asia/Baku Etc/GMT-9
32
- Etc/GMT+1 Etc/GMT+0 Asia/Aden Etc/GMT+2 Etc/GMT+3 Etc/GMT+4 Etc/GMT+5 Etc/GMT+6
33
- Etc/GMT+7 Etc/GMT+8 Etc/GMT+9 Etc/GMT-0 Etc/GMT-1 Universal Asia/Dili Greenwich
34
- Asia/Gaza Etc/GMT-8 Etc/GMT-7 US/Alaska Asia/Oral Etc/GMT-6 Etc/GMT-5 Etc/GMT-4
35
- Asia/Hovd Etc/GMT-3 US/Hawaii Etc/GMT-2 Kwajalein Asia/Omsk Asia/Macao
36
- Etc/GMT-14 Asia/Kabul US/Central Etc/GMT-13 US/Arizona Asia/Macau Asia/Qatar
37
- Asia/Seoul Asia/Tokyo Asia/Dubai US/Pacific Etc/GMT-12 Etc/GMT-11 Etc/GMT-10
38
- Asia/Dhaka Asia/Dacca Asia/Chita Etc/GMT+12 Etc/GMT+10 Asia/Amman Asia/Aqtau
39
- Etc/GMT+11 US/Eastern Asia/Thimbu Asia/Brunei Asia/Tehran Asia/Beirut
40
- Europe/Rome Europe/Riga Brazil/Acre Brazil/East Europe/Oslo Brazil/West
41
- Africa/Lome Asia/Taipei Asia/Saigon Asia/Riyadh Asia/Aqtobe Asia/Anadyr
42
- Europe/Kiev Asia/Almaty Africa/Juba Pacific/Yap US/Aleutian Asia/Muscat
43
- US/Mountain Asia/Harbin Asia/Hebron Asia/Manila Asia/Kuwait Asia/Urumqi
44
- US/Michigan Indian/Mahe SystemV/EST5 Asia/Kashgar Indian/Cocos Asia/Jakarta
45
- Asia/Kolkata Asia/Kuching America/Atka Asia/Irkutsk Pacific/Apia Asia/Magadan
46
- Africa/Dakar America/Lima Pacific/Fiji Pacific/Guam Europe/Vaduz Pacific/Niue
47
- Asia/Nicosia Africa/Ceuta Pacific/Truk America/Adak Pacific/Wake Africa/Tunis
48
- Africa/Cairo Asia/Colombo SystemV/AST4 SystemV/CST6 Asia/Karachi Asia/Rangoon
49
- SystemV/MST7 Asia/Baghdad Europe/Malta Africa/Lagos Europe/Minsk SystemV/PST8
50
- Canada/Yukon Asia/Tbilisi America/Nome Asia/Bahrain Africa/Accra Europe/Paris
51
- Asia/Bangkok Asia/Bishkek Asia/Thimphu SystemV/YST9 Asia/Yerevan Asia/Yakutsk
52
- Europe/Sofia Asia/Ust-Nera Australia/ACT Australia/LHI Europe/Tirane
53
- Asia/Tel_Aviv Australia/NSW Africa/Luanda Asia/Tashkent Africa/Lusaka
54
- Asia/Shanghai Africa/Malabo Asia/Sakhalin Africa/Maputo Africa/Maseru
55
- SystemV/HST10 Africa/Kigali Africa/Niamey Pacific/Samoa America/Sitka
56
- Pacific/Palau Pacific/Nauru Pacific/Efate Asia/Makassar Pacific/Chuuk
57
- Africa/Harare Africa/Douala America/Aruba America/Thule America/Bahia
58
- America/Jujuy America/Belem Asia/Katmandu America/Boise Indian/Comoro
59
- Indian/Chagos Asia/Jayapura Europe/Zurich Asia/Istanbul Europe/Zagreb
60
- Etc/Greenwich Europe/Warsaw Europe/Vienna Etc/Universal Asia/Dushanbe
61
- Europe/Athens Europe/Berlin Africa/Bissau Asia/Damascus Africa/Banjul
62
- Europe/Dublin Africa/Bangui Africa/Bamako Europe/Jersey Africa/Asmera
63
- Europe/Lisbon Africa/Asmara Europe/London Asia/Ashgabat Asia/Calcutta
64
- Europe/Madrid Europe/Monaco Europe/Moscow Europe/Prague Europe/Samara
65
- Europe/Skopje Asia/Khandyga Canada/Pacific Africa/Abidjan America/Manaus
66
- Asia/Chongqing Asia/Chungking Africa/Algiers America/Maceio US/Pacific-New
67
- Africa/Conakry America/La_Paz America/Juneau America/Nassau America/Inuvik
68
- Europe/Andorra Africa/Kampala Asia/Ashkhabad Asia/Hong_Kong America/Havana
69
- Canada/Eastern Europe/Belfast Canada/Central Australia/West Asia/Jerusalem
70
- Africa/Mbabane Asia/Kamchatka America/Virgin America/Guyana Asia/Kathmandu
71
- Mexico/General America/Panama Europe/Nicosia America/Denver Europe/Tallinn
72
- Africa/Nairobi America/Dawson Europe/Vatican Europe/Vilnius America/Cuiaba
73
- Africa/Tripoli Pacific/Wallis Atlantic/Faroe Pacific/Tarawa Pacific/Tahiti
74
- Pacific/Saipan Pacific/Ponape America/Cayman America/Cancun Asia/Pontianak
75
- Asia/Pyongyang Asia/Vientiane Asia/Qyzylorda Pacific/Noumea America/Bogota
76
- Pacific/Midway Pacific/Majuro Asia/Samarkand Indian/Mayotte Pacific/Kosrae
77
- Asia/Singapore Indian/Reunion America/Belize America/Regina America/Recife
78
- Pacific/Easter Mexico/BajaSur America/Merida Pacific/Chatham Pacific/Fakaofo
79
- Pacific/Gambier America/Rosario Asia/Ulan_Bator Indian/Maldives Pacific/Norfolk
80
- America/Antigua Asia/Phnom_Penh America/Phoenix America/Caracas America/Cayenne
81
- Atlantic/Azores Pacific/Pohnpei Atlantic/Canary America/Chicago Atlantic/Faeroe
82
- Africa/Windhoek America/Cordoba America/Creston Africa/Timbuktu America/Curacao
83
- Africa/Sao_Tome Africa/Ndjamena SystemV/AST4ADT Europe/Uzhgorod Europe/Tiraspol
84
- SystemV/CST6CDT Africa/Monrovia America/Detroit Europe/Sarajevo Australia/Eucla
85
- America/Tijuana America/Toronto America/Godthab America/Grenada Europe/Istanbul
86
- America/Ojinaga America/Tortola Australia/Perth Europe/Helsinki Australia/South
87
- Europe/Guernsey SystemV/EST5EDT Europe/Chisinau SystemV/MST7MDT Europe/Busingen
88
- Europe/Budapest Europe/Brussels America/Halifax America/Mendoza America/Noronha
89
- America/Nipigon Canada/Atlantic America/Yakutat SystemV/PST8PDT SystemV/YST9YDT
90
- Canada/Mountain Africa/Kinshasa Africa/Khartoum Africa/Gaborone Africa/Freetown
91
- America/Iqaluit America/Jamaica US/East-Indiana Africa/El_Aaiun America/Knox_IN
92
- Africa/Djibouti Africa/Blantyre America/Moncton America/Managua Asia/Choibalsan
93
- America/Marigot Australia/North Europe/Belgrade America/Resolute
94
- America/Mazatlan Pacific/Funafuti Pacific/Auckland Pacific/Honolulu
95
- Pacific/Johnston America/Miquelon America/Santarem Mexico/BajaNorte
96
- America/Santiago Antarctica/Troll America/Asuncion America/Atikokan
97
- America/Montreal America/Barbados Africa/Bujumbura Pacific/Pitcairn
98
- Asia/Ulaanbaatar Indian/Mauritius America/New_York Antarctica/Syowa
99
- America/Shiprock Indian/Kerguelen Asia/Novosibirsk America/Anguilla
100
- Indian/Christmas Asia/Vladivostok Asia/Ho_Chi_Minh Antarctica/Davis
101
- Atlantic/Bermuda Europe/Amsterdam Antarctica/Casey America/St_Johns
102
- Atlantic/Madeira America/Winnipeg America/St_Kitts Europe/Volgograd
103
- Brazil/DeNoronha Europe/Bucharest Africa/Mogadishu America/St_Lucia
104
- Atlantic/Stanley Europe/Stockholm Australia/Currie Europe/Gibraltar
105
- Australia/Sydney Asia/Krasnoyarsk Australia/Darwin America/Dominica
106
- America/Edmonton America/Eirunepe Europe/Podgorica America/Ensenada
107
- Europe/Ljubljana Australia/Hobart Europe/Mariehamn Africa/Lubumbashi
108
- America/Goose_Bay Europe/Luxembourg America/Menominee America/Glace_Bay
109
- America/Fortaleza Africa/Nouakchott America/Matamoros Pacific/Galapagos
110
- America/Guatemala Pacific/Kwajalein Pacific/Marquesas America/Guayaquil
111
- Asia/Kuala_Lumpur Europe/San_Marino America/Monterrey Europe/Simferopol
112
- America/Araguaina Antarctica/Vostok Europe/Copenhagen America/Catamarca
113
- Pacific/Pago_Pago America/Sao_Paulo America/Boa_Vista America/St_Thomas
114
- Chile/Continental America/Vancouver Africa/Casablanca Europe/Bratislava
115
- Pacific/Enderbury Pacific/Rarotonga Europe/Zaporozhye US/Indiana-Starke
116
- Antarctica/Palmer Asia/Novokuznetsk Africa/Libreville America/Chihuahua
117
- America/Anchorage Pacific/Tongatapu Antarctica/Mawson Africa/Porto-Novo
118
- Asia/Yekaterinburg America/Paramaribo America/Hermosillo Atlantic/Jan_Mayen
119
- Antarctica/McMurdo America/Costa_Rica Antarctica/Rothera America/Grand_Turk
120
- Atlantic/Reykjavik Atlantic/St_Helena Australia/Victoria Chile/EasterIsland
121
- Asia/Ujung_Pandang Australia/Adelaide America/Montserrat America/Porto_Acre
122
- Africa/Brazzaville Australia/Brisbane America/Kralendijk America/Montevideo
123
- America/St_Vincent America/Louisville Australia/Canberra Australia/Tasmania
124
- Europe/Isle_of_Man Europe/Kaliningrad Africa/Ouagadougou America/Rio_Branco
125
- Pacific/Kiritimati Africa/Addis_Ababa America/Metlakatla America/Martinique
126
- Asia/Srednekolymsk America/Guadeloupe America/Fort_Wayne Australia/Lindeman
127
- America/Whitehorse Arctic/Longyearbyen America/Pangnirtung America/Mexico_City
128
- America/Los_Angeles America/Rainy_River Atlantic/Cape_Verde Pacific/Guadalcanal
129
- Indian/Antananarivo America/El_Salvador Australia/Lord_Howe Africa/Johannesburg
130
- America/Tegucigalpa Canada/Saskatchewan America/Thunder_Bay Canada/Newfoundland
131
- America/Puerto_Rico America/Yellowknife Australia/Melbourne America/Porto_Velho
132
- Australia/Queensland Australia/Yancowinna America/Santa_Isabel
133
- America/Blanc-Sablon America/Scoresbysund America/Danmarkshavn
134
- Pacific/Port_Moresby Antarctica/Macquarie America/Buenos_Aires
135
- Africa/Dar_es_Salaam America/Campo_Grande America/Dawson_Creek
136
- America/Indianapolis Pacific/Bougainville America/Rankin_Inlet
137
- America/Indiana/Knox America/Lower_Princes America/Coral_Harbour
138
- America/St_Barthelemy Australia/Broken_Hill America/Cambridge_Bay
139
- America/Indiana/Vevay America/Swift_Current America/Port_of_Spain
140
- Antarctica/South_Pole America/Santo_Domingo Atlantic/South_Georgia
141
- America/Port-au-Prince America/Bahia_Banderas America/Indiana/Winamac
142
- America/Indiana/Marengo America/Argentina/Jujuy America/Argentina/Salta
143
- Canada/East-Saskatchewan America/Indiana/Vincennes America/Argentina/Tucuman
144
- America/Argentina/Ushuaia Antarctica/DumontDUrville America/Indiana/Tell_City
145
- America/Argentina/Mendoza America/Argentina/Cordoba America/Indiana/Petersburg
146
- America/Argentina/San_Luis America/Argentina/San_Juan America/Argentina/La_Rioja
147
- America/North_Dakota/Center America/Kentucky/Monticello
148
- America/North_Dakota/Beulah America/Kentucky/Louisville
149
- America/Argentina/Catamarca America/Indiana/Indianapolis
150
- America/North_Dakota/New_Salem America/Argentina/Rio_Gallegos
151
- America/Argentina/Buenos_Aires America/Argentina/ComodRivadavia
152
- ]
153
- TIMEZONEs = TIMEZONES.collect(&:downcase)
154
-
155
26
  #
156
27
  # Zon{ing|ed}Time, whatever.
157
28
  #
158
29
  class ZoTime
159
30
 
160
- attr_accessor :seconds
161
- attr_accessor :zone
31
+ attr_reader :seconds
32
+ attr_reader :zone
162
33
 
163
34
  def initialize(s, zone)
164
35
 
165
36
  @seconds = s.to_f
166
- @zone = zone
167
- end
37
+ @zone = self.class.get_tzone(zone || :current)
168
38
 
169
- def time
39
+ fail ArgumentError.new(
40
+ "cannot determine timezone from #{zone.inspect}" +
41
+ " (etz:#{ENV['TZ'].inspect},tnz:#{Time.now.zone.inspect}," +
42
+ "tzid:#{defined?(TZInfo::Data).inspect})"
43
+ ) unless @zone
170
44
 
171
- in_zone do
45
+ @time = nil # cache for #to_time result
46
+ end
172
47
 
173
- t = Time.at(@seconds)
48
+ def seconds=(f)
174
49
 
175
- #if t.isdst
176
- # t1 = Time.at(@seconds + 3600)
177
- # t = t1 if t.zone != t1.zone && t.hour == t1.hour && t.min == t1.min
178
- # # ambiguous TZ (getting out of DST)
179
- #else
180
- # t.hour # force t to compute itself
181
- #end
182
- #
183
- # jump out of DST as soon as possible, jumps 1h as seen from UTC
50
+ @time = nil
51
+ @seconds = f
52
+ end
184
53
 
185
- t.hour # force t to compute itself
186
- #
187
- # stay in DST as long as possible, no jump seen from UTC
54
+ def zone=(z)
188
55
 
189
- t
190
- end
56
+ @time = nil
57
+ @zone = self.class.get_tzone(zone || :current)
191
58
  end
192
59
 
193
60
  def utc
194
61
 
195
- time.utc
62
+ Time.utc(1970, 1, 1) + @seconds
196
63
  end
197
64
 
198
- def add(s)
65
+ # Returns a Ruby Time instance.
66
+ #
67
+ # Warning: the timezone of that Time instance will be UTC.
68
+ #
69
+ def to_time
199
70
 
200
- @seconds += s.to_f
71
+ @time ||= begin; u = utc; @zone.period_for_utc(u).to_local(u); end
201
72
  end
202
73
 
203
- def substract(s)
74
+ %w[
75
+ year month day wday hour min sec usec asctime
76
+ ].each do |m|
77
+ define_method(m) { to_time.send(m) }
78
+ end
79
+ def iso8601(fraction_digits=0); to_time.iso8601(fraction_digits); end
80
+
81
+ def ==(o)
82
+
83
+ o.is_a?(ZoTime) && o.seconds == @seconds && o.zone == @zone
84
+ end
85
+ #alias eq? == # FIXME see Object#== (ri)
86
+
87
+ def >(o); @seconds > _to_f(o); end
88
+ def >=(o); @seconds >= _to_f(o); end
89
+ def <(o); @seconds < _to_f(o); end
90
+ def <=(o); @seconds <= _to_f(o); end
91
+ def <=>(o); @seconds <=> _to_f(o); end
92
+
93
+ alias getutc utc
94
+ alias getgm utc
204
95
 
205
- @seconds -= s.to_f
96
+ def to_i
97
+
98
+ @seconds.to_i
206
99
  end
207
100
 
208
101
  def to_f
@@ -210,82 +103,372 @@ America/Argentina/Buenos_Aires America/Argentina/ComodRivadavia
210
103
  @seconds
211
104
  end
212
105
 
213
- #DELTA_TZ_REX = /^[+-][0-1][0-9]:?[0-5][0-9]$/
106
+ def is_dst?
107
+
108
+ @zone.period_for_utc(utc).std_offset != 0
109
+ end
110
+ alias isdst is_dst?
111
+
112
+ def utc_offset
113
+
114
+ #@zone.period_for_utc(utc).utc_offset
115
+ #@zone.period_for_utc(utc).utc_total_offset
116
+ #@zone.period_for_utc(utc).std_offset
117
+ @zone.period_for_utc(utc).utc_offset
118
+ end
119
+
120
+ def strftime(format)
121
+
122
+ format = format.gsub(/%(\/?Z|:{0,2}z)/) { |f| strfz(f) }
123
+
124
+ to_time.strftime(format)
125
+ end
126
+
127
+ def add(t); @time = nil; @seconds += t.to_f; end
128
+ def substract(t); @time = nil; @seconds -= t.to_f; end
129
+
130
+ def +(t); inc(t, 1); end
131
+ def -(t); inc(t, -1); end
132
+
133
+ WEEK_S = 7 * 24 * 3600
134
+
135
+ def monthdays
136
+
137
+ date = to_time
138
+
139
+ pos = 1
140
+ d = self.dup
141
+
142
+ loop do
143
+ d.add(-WEEK_S)
144
+ break if d.month != date.month
145
+ pos = pos + 1
146
+ end
147
+
148
+ neg = -1
149
+ d = self.dup
150
+
151
+ loop do
152
+ d.add(WEEK_S)
153
+ break if d.month != date.month
154
+ neg = neg - 1
155
+ end
156
+
157
+ [ "#{date.wday}##{pos}", "#{date.wday}##{neg}" ]
158
+ end
159
+
160
+ def to_s
214
161
 
215
- def self.envtzable?(s)
162
+ strftime('%Y-%m-%d %H:%M:%S %z')
163
+ end
164
+
165
+ def to_debug_s
166
+
167
+ uo = self.utc_offset
168
+ uos = uo < 0 ? '-' : '+'
169
+ uo = uo.abs
170
+ uoh, uom = [ uo / 3600, uo % 3600 ]
171
+
172
+ [
173
+ 'zt',
174
+ self.strftime('%Y-%m-%d %H:%M:%S'),
175
+ "%s%02d:%02d" % [ uos, uoh, uom ],
176
+ "dst:#{self.isdst}"
177
+ ].join(' ')
178
+ end
179
+
180
+ # Debug current time by showing local time / delta / utc time
181
+ # for example: "0120-7(0820)"
182
+ #
183
+ def to_utc_comparison_s
216
184
 
217
- TIMEZONES.include?(s)
185
+ per = @zone.period_for_utc(utc)
186
+ off = per.utc_total_offset
187
+
188
+ off = off / 3600
189
+ off = off >= 0 ? "+#{off}" : off.to_s
190
+
191
+ strftime('%H%M') + off + utc.strftime('(%H%M)')
192
+ end
193
+
194
+ def to_time_s
195
+
196
+ strftime("%H:%M:%S.#{'%06d' % usec}")
197
+ end
198
+
199
+ def self.now(zone=nil)
200
+
201
+ ZoTime.new(Time.now.to_f, zone)
202
+ end
203
+
204
+ # https://en.wikipedia.org/wiki/ISO_8601
205
+ # Postel's law applies
206
+ #
207
+ def self.extract_iso8601_zone(s)
208
+
209
+ m = s.match(
210
+ /[0-2]\d(?::?[0-6]\d(?::?[0-6]\d))?\s*([+-]\d\d(?::?\d\d)?)\s*\z/)
211
+ return nil unless m
212
+
213
+ zs = m[1].split(':')
214
+ zs << '00' if zs.length < 2
215
+
216
+ zh = zs[0].to_i.abs
217
+
218
+ return nil if zh > 24
219
+ return nil if zh == 24 && zs[1].to_i != 0
220
+
221
+ zs.join(':')
218
222
  end
219
223
 
220
224
  def self.parse(str, opts={})
221
225
 
222
226
  if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
223
- return ZoTime.new(t, ENV['TZ'])
227
+ return ZoTime.new(t, nil)
224
228
  end
225
229
 
230
+ #rold = RUBY_VERSION < '1.9.0'
231
+ #rold = RUBY_VERSION < '2.0.0'
232
+
226
233
  begin
227
234
  DateTime.parse(str)
228
235
  rescue
229
- fail ArgumentError, "no time information in #{o.inspect}"
230
- end if RUBY_VERSION < '1.9.0'
236
+ fail ArgumentError, "no time information in #{str.inspect}"
237
+ end #if rold
238
+ #
239
+ # is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now`
231
240
 
232
241
  zone = nil
233
242
 
234
243
  s =
235
- str.gsub(/\S+/) { |m|
236
- if envtzable?(m)
237
- zone ||= m
244
+ str.gsub(/\S+/) do |w|
245
+ if z = get_tzone(w)
246
+ zone ||= z
238
247
  ''
239
248
  else
240
- m
249
+ w
241
250
  end
242
- }
251
+ end
252
+
253
+ local = Time.parse(s)
254
+ izone = extract_iso8601_zone(s)
255
+
256
+ zone ||=
257
+ if s.match(/\dZ\b/)
258
+ get_tzone('Zulu')
259
+ #elsif rold && izone
260
+ elsif izone
261
+ get_tzone(izone)
262
+ elsif local.zone.nil? && izone
263
+ get_tzone(local.strftime('%:z'))
264
+ else
265
+ get_tzone(:local)
266
+ end
267
+
268
+ secs =
269
+ #if rold && izone
270
+ if izone
271
+ local.to_f
272
+ else
273
+ zone.period_for_local(local).to_utc(local).to_f
274
+ end
275
+
276
+ ZoTime.new(secs, zone)
277
+ end
243
278
 
244
- return nil unless zone.nil? || is_timezone?(zone)
279
+ def self.get_tzone(str)
280
+ return str if str.is_a?(::TZInfo::Timezone)
245
281
 
246
- zt = ZoTime.new(0, zone || ENV['TZ'])
247
- zt.in_zone { zt.seconds = Time.parse(s).to_f }
282
+ # discard quickly when it's certainly not a timezone
248
283
 
249
- zt.seconds == nil ? nil : zt
250
- end
284
+ return nil if str == nil
285
+ return nil if str == '*'
251
286
 
252
- def self.is_timezone?(str)
287
+ # ok, it's a timezone then
253
288
 
254
- return false if str == nil
255
- return false if str == '*'
289
+ ostr = str
290
+ str = ENV['TZ'] || Time.now.zone if str == :current || str == :local
256
291
 
257
- return false if str.index('#')
258
- # "sun#2", etc... On OSX would go all the way to true
292
+ # utc_offset
259
293
 
260
- return true if Time.zone_offset(str)
294
+ if str.is_a?(Numeric)
295
+ i = str.to_i
296
+ sn = i < 0 ? '-' : '+'; i = i.abs
297
+ hr = i / 3600; mn = i % 3600; sc = i % 60
298
+ str = (sc > 0 ? "%s%02d:%02d:%02d" : "%s%02d:%02d") % [ sn, hr, mn, sc ]
299
+ end
300
+
301
+ return nil if str.nil? || str.index('#')
302
+ # counters "sun#2", etc... On OSX would go all the way to true
303
+
304
+ # vanilla time zones
305
+
306
+ z = (::TZInfo::Timezone.get(str) rescue nil)
307
+ return z if z
308
+
309
+ # time zone abbreviations
310
+
311
+ if str.match(/\A[A-Z0-9-]{3,6}\z/)
261
312
 
262
- return !! (::TZInfo::Timezone.get(str) rescue nil) if defined?(::TZInfo)
313
+ toff = Time.now.utc_offset
314
+ toff = nil if str != Time.now.zone
315
+
316
+ twin = Time.utc(Time.now.year, 1, 1) # winter
317
+ tsum = Time.utc(Time.now.year, 7, 1) # summer
318
+
319
+ z =
320
+ ::TZInfo::Timezone.all.find do |tz|
321
+
322
+ pwin = tz.period_for_utc(twin)
323
+ psum = tz.period_for_utc(tsum)
324
+
325
+ if toff
326
+ (pwin.abbreviation.to_s == str && pwin.utc_offset == toff) ||
327
+ (psum.abbreviation.to_s == str && psum.utc_offset == toff)
328
+ else
329
+ # returns the first tz with the given abbreviation, almost useless
330
+ # favour fully named zones...
331
+ pwin.abbreviation.to_s == str ||
332
+ psum.abbreviation.to_s == str
333
+ end
334
+ end
335
+ return z if z
336
+ end
263
337
 
264
- return true if TIMEZONES.include?(str)
265
- return true if TIMEZONEs.include?(str)
338
+ # some time zone aliases
266
339
 
267
- t = ZoTime.new(0, str).time
340
+ return ::TZInfo::Timezone.get('Zulu') if %w[ Z ].include?(str)
268
341
 
269
- return false if t.zone == ''
270
- return false if t.zone == 'UTC'
271
- return false if t.utc_offset == 0 && str.start_with?(t.zone)
272
- # 3 common fallbacks...
342
+ # custom timezones, no DST, just an offset, like "+08:00" or "-01:30"
273
343
 
274
- return false if RUBY_PLATFORM.include?('java') && ! envtzable?(str)
344
+ tz = (@custom_tz_cache ||= {})[str]
345
+ return tz if tz
275
346
 
276
- true
347
+ if m = str.match(/\A([+-][0-1][0-9]):?([0-5][0-9])\z/)
348
+
349
+ hr = m[1].to_i
350
+ mn = m[2].to_i
351
+
352
+ hr = nil if hr.abs > 11
353
+ hr = nil if mn > 59
354
+ mn = -mn if hr && hr < 0
355
+
356
+ return (
357
+ @custom_tz_cache[str] =
358
+ begin
359
+ tzi = TZInfo::TransitionDataTimezoneInfo.new(str)
360
+ tzi.offset(str, hr * 3600 + mn * 60, 0, str)
361
+ tzi.create_timezone
362
+ end
363
+ ) if hr
364
+ end
365
+
366
+ # last try with ENV['TZ']
367
+
368
+ z =
369
+ (ostr == :local || ostr == :current) &&
370
+ (::TZInfo::Timezone.get(ENV['TZ']) rescue nil)
371
+ return z if z
372
+
373
+ # so it's not a timezone.
374
+
375
+ nil
376
+ end
377
+
378
+ def self.local_tzone
379
+
380
+ get_tzone(:local)
277
381
  end
278
382
 
279
- def in_zone(&block)
383
+ def self.make(o)
384
+
385
+ zt =
386
+ case o
387
+ when Time
388
+ ZoTime.new(o.to_f, o.zone)
389
+ when Date
390
+ t =
391
+ o.respond_to?(:to_time) ?
392
+ o.to_time :
393
+ Time.parse(o.strftime('%Y-%m-%d %H:%M:%S'))
394
+ ZoTime.new(t.to_f, t.zone)
395
+ when String
396
+ Rufus::Scheduler.parse_in(o, :no_error => true) || self.parse(o)
397
+ else
398
+ o
399
+ end
400
+
401
+ zt = ZoTime.new(Time.now.to_f + zt, nil) if zt.is_a?(Numeric)
402
+
403
+ fail ArgumentError.new(
404
+ "cannot turn #{o.inspect} to a ZoTime instance"
405
+ ) unless zt.is_a?(ZoTime)
406
+
407
+ zt
408
+ end
409
+
410
+ # def in_zone(&block)
411
+ #
412
+ # current_timezone = ENV['TZ']
413
+ # ENV['TZ'] = @zone
414
+ #
415
+ # block.call
416
+ #
417
+ # ensure
418
+ #
419
+ # ENV['TZ'] = current_timezone
420
+ # end
421
+
422
+ protected
423
+
424
+ def inc(t, dir)
425
+
426
+ if t.is_a?(Numeric)
427
+ nt = self.dup
428
+ nt.seconds += dir * t.to_f
429
+ nt
430
+ elsif t.respond_to?(:to_f)
431
+ @seconds + dir * t.to_f
432
+ else
433
+ fail ArgumentError.new(
434
+ "cannot call ZoTime #- or #+ with arg of class #{t.class}")
435
+ end
436
+ end
437
+
438
+ def _to_f(o)
439
+
440
+ fail ArgumentError(
441
+ "comparison of ZoTime with #{o.inspect} failed"
442
+ ) unless o.is_a?(ZoTime) || o.is_a?(Time)
443
+
444
+ o.to_f
445
+ end
446
+
447
+ def strfz(code)
448
+
449
+ return @zone.name if code == '%/Z'
450
+
451
+ per = @zone.period_for_utc(utc)
280
452
 
281
- current_timezone = ENV['TZ']
282
- ENV['TZ'] = @zone
453
+ return per.abbreviation.to_s if code == '%Z'
283
454
 
284
- block.call
455
+ off = per.utc_total_offset
456
+ #
457
+ sn = off < 0 ? '-' : '+'; off = off.abs
458
+ hr = off / 3600
459
+ mn = (off % 3600) / 60
460
+ sc = 0
285
461
 
286
- ensure
462
+ fmt =
463
+ if code == '%z'
464
+ "%s%02d%02d"
465
+ elsif code == '%:z'
466
+ "%s%02d:%02d"
467
+ else
468
+ "%s%02d:%02d:%02d"
469
+ end
287
470
 
288
- ENV['TZ'] = current_timezone
471
+ fmt % [ sn, hr, mn, sc ]
289
472
  end
290
473
  end
291
474
  end
@@ -31,6 +31,10 @@ module RocketJob
31
31
 
32
32
  included do
33
33
  include AASM
34
+ # Try to make aasm lookup thread safe
35
+ @aasm = Concurrent::Map.new
36
+ # Call aasm to create default instance upfront
37
+ aasm
34
38
 
35
39
  # Adds a :before or :after callback to an event
36
40
  # state_machine_add_event_callback(:start, :before, :my_method)
@@ -202,6 +202,19 @@ module RocketJob
202
202
  self.class.shutdown? || !running?
203
203
  end
204
204
 
205
+ # Scope for all zombie servers
206
+ def self.zombies(missed = 4)
207
+ dead_seconds = Config.instance.heartbeat_seconds * missed
208
+ last_heartbeat_time = Time.now - dead_seconds
209
+ where(
210
+ :state.in => [:stopping, :running, :paused],
211
+ '$or' => [
212
+ {"heartbeat.updated_at" => {'$exists' => false}},
213
+ {"heartbeat.updated_at" => {'$lte' => last_heartbeat_time}}
214
+ ]
215
+ )
216
+ end
217
+
205
218
  # Returns [true|false] if this server has missed at least the last 4 heartbeats
206
219
  #
207
220
  # Possible causes for a server to miss its heartbeats:
@@ -209,7 +222,7 @@ module RocketJob
209
222
  # - The server process is "hanging"
210
223
  # - The server is no longer able to communicate with the MongoDB Server
211
224
  def zombie?(missed = 4)
212
- return false unless running? || stopping?
225
+ return false unless running? || stopping? || paused?
213
226
  return true if heartbeat.nil? || heartbeat.updated_at.nil?
214
227
  dead_seconds = Config.instance.heartbeat_seconds * missed
215
228
  (Time.now - heartbeat.updated_at) >= dead_seconds
@@ -258,7 +271,7 @@ module RocketJob
258
271
  ensure
259
272
  # Logs the backtrace for each running worker
260
273
  if SemanticLogger::VERSION.to_i >= 4
261
- workers.each { |thread| logger.backtrace(thread: thread) }
274
+ workers.each { |worker| logger.backtrace(thread: worker.thread) }
262
275
  end
263
276
  end
264
277
 
@@ -1,4 +1,4 @@
1
1
  # encoding: UTF-8
2
2
  module RocketJob #:nodoc
3
- VERSION = '3.0.0.rc5'
3
+ VERSION = '3.0.0'
4
4
  end
@@ -32,7 +32,7 @@ module Plugins
32
32
 
33
33
  describe 'timezones are supported' do
34
34
  it 'handles UTC' do
35
- time = Time.parse('2015-12-09 17:50:05 +0000')
35
+ time = Time.parse('2015-12-09 17:50:05 UTC')
36
36
  Time.stub(:now, time) do
37
37
  @job = CronJob.create!(cron_schedule: '* 1 * * * UTC')
38
38
  end
@@ -42,7 +42,7 @@ module Plugins
42
42
  end
43
43
 
44
44
  it 'handles Eastern' do
45
- time = Time.parse('2015-12-09 17:50:05 +0000')
45
+ time = Time.parse('2015-12-09 17:50:05 UTC')
46
46
  Time.stub(:now, time) do
47
47
  @job = CronJob.create!(cron_schedule: '* 1 * * * America/New_York')
48
48
  end
@@ -32,7 +32,7 @@ module Plugins
32
32
 
33
33
  describe 'timezones are supported' do
34
34
  it 'handles UTC' do
35
- time = Time.parse('2015-12-09 17:50:05 +0000')
35
+ time = Time.parse('2015-12-09 17:50:05 UTC')
36
36
  Time.stub(:now, time) do
37
37
  @job = ProcessingWindowJob.create!(processing_schedule: '* 1 * * * UTC', processing_duration: 1.hour)
38
38
  end
@@ -42,7 +42,7 @@ module Plugins
42
42
  end
43
43
 
44
44
  it 'handles Eastern' do
45
- time = Time.parse('2015-12-09 17:50:05 +0000')
45
+ time = Time.parse('2015-12-09 17:50:05 UTC')
46
46
  Time.stub(:now, time) do
47
47
  @job = ProcessingWindowJob.create!(processing_schedule: '* 1 * * * America/New_York', processing_duration: 1.hour)
48
48
  end
@@ -55,7 +55,7 @@ module Plugins
55
55
 
56
56
  describe '#rocket_job_processing_window_active?' do
57
57
  it 'returns true when in the processing window' do
58
- time = Time.parse('2015-12-09 17:50:05 +0000')
58
+ time = Time.parse('2015-12-09 17:50:05 UTC')
59
59
  @job = ProcessingWindowJob.new(processing_schedule: '* 17 * * * UTC', processing_duration: 1.hour)
60
60
  result = Time.stub(:now, time) do
61
61
  @job.rocket_job_processing_window_active?
@@ -64,7 +64,7 @@ module Plugins
64
64
  end
65
65
 
66
66
  it 'returns false when not in the processing window' do
67
- time = Time.parse('2015-12-09 16:50:05 +0000')
67
+ time = Time.parse('2015-12-09 16:50:05 UTC')
68
68
  @job = ProcessingWindowJob.new(processing_schedule: '* 17 * * * UTC', processing_duration: 1.hour)
69
69
  result = Time.stub(:now, time) do
70
70
  @job.rocket_job_processing_window_active?
@@ -96,7 +96,7 @@ module Plugins
96
96
 
97
97
  describe 're-queue' do
98
98
  it 'if outside processing window' do
99
- time = Time.parse('2015-12-09 16:50:05 +0000')
99
+ time = Time.parse('2015-12-09 16:50:05 UTC')
100
100
  Time.stub(:now, time) do
101
101
  @job = ProcessingWindowJob.new(processing_schedule: '* 17 * * * UTC', processing_duration: 1.hour)
102
102
  @job.perform_now
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rocketjob
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0.rc5
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Reid Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-11 00:00:00.000000000 Z
11
+ date: 2017-01-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -165,9 +165,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
165
165
  version: '2.1'
166
166
  required_rubygems_version: !ruby/object:Gem::Requirement
167
167
  requirements:
168
- - - ">"
168
+ - - ">="
169
169
  - !ruby/object:Gem::Version
170
- version: 1.3.1
170
+ version: '0'
171
171
  requirements: []
172
172
  rubyforge_project:
173
173
  rubygems_version: 2.6.8