fugit 1.1.8 → 1.1.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -0
- data/CREDITS.md +2 -1
- data/README.md +2 -1
- data/lib/fugit.rb +1 -1
- data/lib/fugit/cron.rb +61 -54
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 35836e95c82a113fe2e5222a02522ab2bf36f1b0
|
4
|
+
data.tar.gz: 0fb6db1cb77893af937354da715b2eb8b14403f5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7de61477e96c9612542641787346fb154394d8388eccccaeb1be257cb57410abe4e23d1377148539d92852674df3c58d0a44c9cc4816c50cd157515f185d59da
|
7
|
+
data.tar.gz: c1f23c4a8395ddc29a85415300608fbc45d5900cbb42c502fd51f02f7f8c5f6fe945fe9b010349e9bde6fc1df6f3ec105a977c8705722820be41c65b47656ff7
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,14 @@
|
|
2
2
|
# CHANGELOG.md
|
3
3
|
|
4
4
|
|
5
|
+
## fugit 1.1.9 released 2019-03-26
|
6
|
+
|
7
|
+
* Fix cron `"0 9 29 feb *"` endless loop, gh-18
|
8
|
+
* Fix cron endless loop when #previous_time(t) and t matches, gh-15
|
9
|
+
* Simplify Cron #next_time / #previous_time breaker system, gh-15
|
10
|
+
Thanks @godfat and @conet
|
11
|
+
|
12
|
+
|
5
13
|
## fugit 1.1.8 released 2019-01-17
|
6
14
|
|
7
15
|
* Ensure Cron#next_time happens in cron's time zone, gh-12
|
data/CREDITS.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
# fugit credits
|
3
3
|
|
4
|
+
* Cristian Oneț https://githbu.com/conet #previous_time vs 1/-1 endless loop #15
|
4
5
|
* Wenhui Wang https://github.com/w11th #next_time vs Chronic+ActiveSupport #11
|
5
6
|
* Lin-Jen Shin https://github.com/godfat #next_time untamed loop, #13
|
6
7
|
* Nils Mueller https://github.com/Tolsto missing Olson timezone names, #9
|
@@ -17,5 +18,5 @@
|
|
17
18
|
As fugit originates in rufus-scheduler, many thanks to all the
|
18
19
|
rufus-scheduler contributors and people who gave feedback.
|
19
20
|
|
20
|
-
https://github.com/jmettraux/rufus-scheduler/blob/master/CREDITS.
|
21
|
+
https://github.com/jmettraux/rufus-scheduler/blob/master/CREDITS.md
|
21
22
|
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
[![Build Status](https://secure.travis-ci.org/floraison/fugit.svg)](http://travis-ci.org/floraison/fugit)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/fugit.svg)](http://badge.fury.io/rb/fugit)
|
6
|
+
[![Join the chat at https://gitter.im/floraison/fugit](https://badges.gitter.im/floraison/fugit.svg)](https://gitter.im/floraison/fugit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
6
7
|
|
7
8
|
Time tools for [flor](https://github.com/floraison/flor) and the floraison group.
|
8
9
|
|
@@ -34,9 +35,9 @@ The intersection of those two projects is where fugit is born:
|
|
34
35
|
* [sideqik-cron](https://github.com/ondrejbartas/sidekiq-cron) - recent versions of Sideqik-Cron use fugit to parse cron strings
|
35
36
|
* [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler) -
|
36
37
|
* [flor](https://github.com/floraison/flor) - used in the [cron](https://github.com/floraison/flor/blob/master/doc/procedures/cron.md) procedure
|
38
|
+
* [que-scheduler](https://github.com/hlascelles/que-scheduler) - a reliable job scheduler for [que](https://github.com/chanks/que)
|
37
39
|
* ...
|
38
40
|
|
39
|
-
|
40
41
|
## `Fugit.parse(s)`
|
41
42
|
|
42
43
|
The simplest way to use fugit is via `Fugit.parse(s)`.
|
data/lib/fugit.rb
CHANGED
data/lib/fugit/cron.rb
CHANGED
@@ -64,7 +64,8 @@ module Fugit
|
|
64
64
|
|
65
65
|
class TimeCursor
|
66
66
|
|
67
|
-
def initialize(t)
|
67
|
+
def initialize(cron, t)
|
68
|
+
@cron = cron
|
68
69
|
@t = t.is_a?(TimeCursor) ? t.time : t
|
69
70
|
@t.seconds = @t.seconds.to_i
|
70
71
|
end
|
@@ -88,28 +89,49 @@ module Fugit
|
|
88
89
|
@t = ::EtOrbi.make(y, m, @t.zone)
|
89
90
|
self
|
90
91
|
end
|
91
|
-
def inc_day; inc((24 - @t.hour) * 3600 - @t.min * 60 - @t.sec); end
|
92
|
-
def inc_hour; inc((60 - @t.min) * 60 - @t.sec); end
|
93
|
-
def inc_min; inc(60 - @t.sec); end
|
94
92
|
|
95
|
-
def
|
96
|
-
|
93
|
+
def inc_day
|
94
|
+
inc((24 - @t.hour) * 3600 - @t.min * 60 - @t.sec)
|
95
|
+
end
|
96
|
+
def inc_hour
|
97
|
+
inc((60 - @t.min) * 60 - @t.sec)
|
98
|
+
end
|
99
|
+
def inc_min
|
100
|
+
inc(60 - @t.sec)
|
101
|
+
end
|
102
|
+
|
103
|
+
def inc_sec
|
104
|
+
if sec = @cron.seconds.find { |s| s > @t.sec }
|
97
105
|
inc(sec - @t.sec)
|
98
106
|
else
|
99
|
-
inc(60 - @t.sec + seconds.first)
|
107
|
+
inc(60 - @t.sec + @cron.seconds.first)
|
100
108
|
end
|
101
109
|
end
|
102
110
|
|
103
111
|
def dec_month
|
104
|
-
|
112
|
+
|
113
|
+
#dec(@t.day * 24 * 3600 + @t.hour * 3600 + @t.min * 60 + @t.sec + 1)
|
114
|
+
#
|
115
|
+
# gh-18, so that '0 9 29 feb *' doesn't get skipped (over and over)
|
116
|
+
#
|
117
|
+
dec(@t.day * 24 * 3600 + 1)
|
118
|
+
end
|
119
|
+
|
120
|
+
def dec_day
|
121
|
+
dec(@t.hour * 3600 + @t.min * 60 + @t.sec + 1)
|
122
|
+
end
|
123
|
+
def dec_hour
|
124
|
+
dec(@t.min * 60 + @t.sec + 1)
|
125
|
+
end
|
126
|
+
def dec_min
|
127
|
+
dec(@t.sec + 1)
|
105
128
|
end
|
106
|
-
def dec_day; dec(@t.hour * 3600 + @t.min * 60 + @t.sec + 1); end
|
107
|
-
def dec_hour; dec(@t.min * 60 + @t.sec + 1); end
|
108
|
-
def dec_min; dec(@t.sec + 1); end
|
109
129
|
|
110
|
-
def dec_sec
|
111
|
-
target =
|
112
|
-
|
130
|
+
def dec_sec
|
131
|
+
target =
|
132
|
+
@cron.seconds.reverse.find { |s| s < @t.sec } ||
|
133
|
+
@cron.seconds.last
|
134
|
+
inc(target - @t.sec - (@t.sec > target ? 0 : 60))
|
113
135
|
end
|
114
136
|
end
|
115
137
|
|
@@ -140,7 +162,7 @@ module Fugit
|
|
140
162
|
|
141
163
|
return true if @monthdays.nil?
|
142
164
|
|
143
|
-
last = (TimeCursor.new(nt).inc_month.time - 24 * 3600).day + 1
|
165
|
+
last = (TimeCursor.new(self, nt).inc_month.time - 24 * 3600).day + 1
|
144
166
|
|
145
167
|
@monthdays
|
146
168
|
.collect { |d| d < 1 ? last + d : d }
|
@@ -166,47 +188,43 @@ module Fugit
|
|
166
188
|
hour_match?(t) && min_match?(t) && sec_match?(t)
|
167
189
|
end
|
168
190
|
|
169
|
-
|
170
|
-
#
|
191
|
+
MAX_ITERATION_COUNT = 2048
|
192
|
+
#
|
193
|
+
# See gh-15 and tst/iteration_count.rb
|
194
|
+
#
|
195
|
+
# Initially set to 1024 after seeing the worst case for #next_time
|
196
|
+
# at 167 iterations, I placed it at 2048 after experimenting with
|
197
|
+
# gh-18 and noticing some > 1024 for some experiments. 2048 should
|
198
|
+
# be ok.
|
171
199
|
|
172
200
|
def next_time(from=::EtOrbi::EoTime.now)
|
173
201
|
|
174
202
|
from = ::EtOrbi.make_time(from)
|
175
|
-
sfrom = from.strftime('%F
|
203
|
+
sfrom = from.strftime('%F|%T')
|
176
204
|
ifrom = from.to_i
|
177
205
|
|
178
|
-
|
206
|
+
i = 0
|
207
|
+
t = TimeCursor.new(self, from.translate(@timezone))
|
179
208
|
#
|
180
209
|
# the translation occurs in the timezone of
|
181
210
|
# this Fugit::Cron instance
|
182
211
|
|
183
|
-
ti = 0
|
184
|
-
stalling = false
|
185
|
-
|
186
212
|
loop do
|
187
213
|
|
188
|
-
ti1 = t.to_i
|
189
|
-
|
190
|
-
fail RuntimeError.new(
|
191
|
-
"loop stalled for #{@original.inspect} #next_time, breaking"
|
192
|
-
) if stalling && ti == ti1
|
193
|
-
|
194
|
-
stalling = (ti == ti1)
|
195
|
-
ti = ti1
|
196
|
-
|
197
214
|
fail RuntimeError.new(
|
198
|
-
"too many loops for #{@original.inspect} #next_time, breaking"
|
199
|
-
|
215
|
+
"too many loops for #{@original.inspect} #next_time, breaking, " +
|
216
|
+
"please fill an issue at https://git.io/fjJC9"
|
217
|
+
) if (i += 1) > MAX_ITERATION_COUNT
|
200
218
|
|
201
|
-
(ifrom ==
|
219
|
+
(ifrom == t.to_i) && (t.inc(1); next)
|
202
220
|
month_match?(t) || (t.inc_month; next)
|
203
221
|
day_match?(t) || (t.inc_day; next)
|
204
222
|
hour_match?(t) || (t.inc_hour; next)
|
205
223
|
min_match?(t) || (t.inc_min; next)
|
206
|
-
sec_match?(t) || (t.inc_sec
|
224
|
+
sec_match?(t) || (t.inc_sec; next)
|
207
225
|
|
208
|
-
st = t.time.strftime('%F
|
209
|
-
(from, sfrom, ifrom = t.time, st, t.
|
226
|
+
st = t.time.strftime('%F|%T')
|
227
|
+
(from, sfrom, ifrom = t.time, st, t.to_i; next) if st == sfrom
|
210
228
|
#
|
211
229
|
# when transitioning out of DST, this prevents #next_time from
|
212
230
|
# yielding the same literal time twice in a row, see gh-6
|
@@ -223,33 +241,22 @@ module Fugit
|
|
223
241
|
def previous_time(from=::EtOrbi::EoTime.now)
|
224
242
|
|
225
243
|
from = ::EtOrbi.make_time(from)
|
226
|
-
ti = 0
|
227
|
-
ifrom = from.to_i
|
228
244
|
|
229
|
-
|
230
|
-
|
245
|
+
i = 0
|
246
|
+
t = TimeCursor.new(self, (from - 1).translate(@timezone))
|
231
247
|
|
232
248
|
loop do
|
233
249
|
|
234
|
-
ti1 = t.to_i
|
235
|
-
|
236
|
-
fail RuntimeError.new(
|
237
|
-
"loop stalled for #{@original.inspect} #previous_time, breaking"
|
238
|
-
) if stalling && ti == ti1
|
239
|
-
|
240
|
-
stalling = (ti == ti1)
|
241
|
-
ti = ti1
|
242
|
-
|
243
250
|
fail RuntimeError.new(
|
244
|
-
"too many loops for #{@original.inspect} #previous_time, breaking"
|
245
|
-
|
251
|
+
"too many loops for #{@original.inspect} #previous_time, breaking, " +
|
252
|
+
"please fill an issue at https://git.io/fjJCQ"
|
253
|
+
) if (i += 1) > MAX_ITERATION_COUNT
|
246
254
|
|
247
|
-
(ifrom == ti) && (t.inc(-1); next)
|
248
255
|
month_match?(t) || (t.dec_month; next)
|
249
256
|
day_match?(t) || (t.dec_day; next)
|
250
257
|
hour_match?(t) || (t.dec_hour; next)
|
251
258
|
min_match?(t) || (t.dec_min; next)
|
252
|
-
sec_match?(t) || (t.dec_sec
|
259
|
+
sec_match?(t) || (t.dec_sec; next)
|
253
260
|
break
|
254
261
|
end
|
255
262
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fugit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-03-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: raabro
|