rufus-scheduler 3.0.4 → 3.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +7 -1
- data/CREDITS.txt +2 -0
- data/README.md +67 -1
- data/lib/rufus/scheduler.rb +1 -1
- data/lib/rufus/scheduler/jobs.rb +33 -12
- data/out.txt +8 -0
- data/spec/job_repeat_spec.rb +23 -0
- data/spec/job_spec.rb +64 -0
- metadata +4 -3
data/CHANGELOG.txt
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
= rufus-scheduler CHANGELOG.txt
|
3
3
|
|
4
4
|
|
5
|
-
== rufus-scheduler - 3.0.
|
5
|
+
== rufus-scheduler - 3.0.5 released 2014/01/30
|
6
|
+
|
7
|
+
- implement Job#call(do_rescue=false), gh-97
|
8
|
+
- implement :first => :now for repeat jobs, gh-96
|
9
|
+
|
10
|
+
|
11
|
+
== rufus-scheduler - 3.0.4 released 2014/01/19
|
6
12
|
|
7
13
|
- make CronLine#frequency faster (to avoid 20s schedule_cron times)
|
8
14
|
|
data/CREDITS.txt
CHANGED
@@ -30,6 +30,8 @@
|
|
30
30
|
|
31
31
|
== Feedback
|
32
32
|
|
33
|
+
- Joe Taylor and Agis Anastasopoulos -
|
34
|
+
http://stackoverflow.com/questions/21280870 - :first => :now and Job#call
|
33
35
|
- Gatis Tomsons - https://github.io/gacha - heavy work threads and lock errors
|
34
36
|
- https://github.com/joast - missing .to_time_string alias (code and doc)
|
35
37
|
- Tamir Duberstein - https://github.com/tamird - rdoc inaccuracies
|
data/README.md
CHANGED
@@ -366,7 +366,7 @@ end
|
|
366
366
|
|
367
367
|
The :timeout option accepts either a duration (like "1d" or "2w3d") or a point in time (like "2013/12/12 12:00").
|
368
368
|
|
369
|
-
### :first_at, :first_in, :first
|
369
|
+
### :first_at, :first_in, :first, :first_time
|
370
370
|
|
371
371
|
This option is for repeat jobs (cron / every) only.
|
372
372
|
|
@@ -393,6 +393,34 @@ job.first_at = Time.now + 10
|
|
393
393
|
job.first_at = Rufus::Scheduler.parse('2029-12-12')
|
394
394
|
```
|
395
395
|
|
396
|
+
The first argument (in all its flavours) accepts a :now or :immediately value. That schedules the first occurence for immediate triggering. Consider:
|
397
|
+
|
398
|
+
```ruby
|
399
|
+
require 'rufus-scheduler'
|
400
|
+
|
401
|
+
s = Rufus::Scheduler.new
|
402
|
+
|
403
|
+
n = Time.now; p [ :scheduled_at, n, n.to_f ]
|
404
|
+
|
405
|
+
s.every '3s', :first => :now do
|
406
|
+
n = Time.now; p [ :in, n, n.to_f ]
|
407
|
+
end
|
408
|
+
|
409
|
+
s.join
|
410
|
+
|
411
|
+
```
|
412
|
+
|
413
|
+
that'll output something like:
|
414
|
+
|
415
|
+
```
|
416
|
+
[:scheduled_at, 2014-01-22 22:21:21 +0900, 1390396881.344438]
|
417
|
+
[:in, 2014-01-22 22:21:21 +0900, 1390396881.6453865]
|
418
|
+
[:in, 2014-01-22 22:21:24 +0900, 1390396884.648807]
|
419
|
+
[:in, 2014-01-22 22:21:27 +0900, 1390396887.651686]
|
420
|
+
[:in, 2014-01-22 22:21:30 +0900, 1390396890.6571937]
|
421
|
+
...
|
422
|
+
```
|
423
|
+
|
396
424
|
### :last_at, :last_in, :last
|
397
425
|
|
398
426
|
This option is for repeat jobs (cron / every) only.
|
@@ -671,6 +699,44 @@ job.keys
|
|
671
699
|
|
672
700
|
Job-local variables are thread-safe.
|
673
701
|
|
702
|
+
### call
|
703
|
+
|
704
|
+
Job instances have a #call method. It simply calls the scheduled block or callable immediately.
|
705
|
+
|
706
|
+
```ruby
|
707
|
+
job =
|
708
|
+
@scheduler.schedule_every '10m' do |job|
|
709
|
+
# ...
|
710
|
+
end
|
711
|
+
|
712
|
+
job.call
|
713
|
+
```
|
714
|
+
|
715
|
+
Warning: the Scheduler#on_error handler is not involved. Error handling is the responsibility of the caller.
|
716
|
+
|
717
|
+
If the call has to be rescued by the error handler of the scheduler, ```call(true)``` might help:
|
718
|
+
|
719
|
+
```ruby
|
720
|
+
require 'rufus-scheduler'
|
721
|
+
|
722
|
+
s = Rufus::Scheduler.new
|
723
|
+
|
724
|
+
def s.on_error(job, err)
|
725
|
+
p [ 'error in scheduled job', job.class, job.original, err.message ]
|
726
|
+
rescue
|
727
|
+
p $!
|
728
|
+
end
|
729
|
+
|
730
|
+
job =
|
731
|
+
s.schedule_in('1d') do
|
732
|
+
fail 'again'
|
733
|
+
end
|
734
|
+
|
735
|
+
job.call(true)
|
736
|
+
#
|
737
|
+
# true lets the error_handler deal with error in the job call
|
738
|
+
```
|
739
|
+
|
674
740
|
## AtJob and InJob methods
|
675
741
|
|
676
742
|
### time
|
data/lib/rufus/scheduler.rb
CHANGED
data/lib/rufus/scheduler/jobs.rb
CHANGED
@@ -183,6 +183,15 @@ module Rufus
|
|
183
183
|
#
|
184
184
|
# might be necessary at some point
|
185
185
|
|
186
|
+
# Calls the callable (usually a block) wrapped in this Job instance.
|
187
|
+
#
|
188
|
+
# Warning: error rescueing is the responsibity of the caller.
|
189
|
+
#
|
190
|
+
def call(do_rescue=false)
|
191
|
+
|
192
|
+
do_call(Time.now, do_rescue)
|
193
|
+
end
|
194
|
+
|
186
195
|
protected
|
187
196
|
|
188
197
|
def callback(meth, time)
|
@@ -209,6 +218,22 @@ module Rufus
|
|
209
218
|
m.is_a?(Mutex) ? m : (@scheduler.mutexes[m.to_s] ||= Mutex.new)
|
210
219
|
end
|
211
220
|
|
221
|
+
def do_call(time, do_rescue)
|
222
|
+
|
223
|
+
args = [ self, time ][0, @callable.arity]
|
224
|
+
@callable.call(*args)
|
225
|
+
|
226
|
+
rescue StandardError => se
|
227
|
+
|
228
|
+
raise se unless do_rescue
|
229
|
+
|
230
|
+
return if se.is_a?(KillSignal) # discard
|
231
|
+
|
232
|
+
@scheduler.on_error(self, se)
|
233
|
+
|
234
|
+
# exceptions above StandardError do pass through
|
235
|
+
end
|
236
|
+
|
212
237
|
def do_trigger(time)
|
213
238
|
|
214
239
|
t = Time.now
|
@@ -220,16 +245,7 @@ module Rufus
|
|
220
245
|
|
221
246
|
@last_time = t
|
222
247
|
|
223
|
-
|
224
|
-
@callable.call(*args)
|
225
|
-
|
226
|
-
rescue KillSignal
|
227
|
-
|
228
|
-
# discard
|
229
|
-
|
230
|
-
rescue StandardError => se
|
231
|
-
|
232
|
-
@scheduler.on_error(self, se)
|
248
|
+
do_call(time, true)
|
233
249
|
|
234
250
|
ensure
|
235
251
|
|
@@ -368,19 +384,24 @@ module Rufus
|
|
368
384
|
) unless @times == nil || @times.is_a?(Fixnum)
|
369
385
|
|
370
386
|
self.first_at =
|
371
|
-
opts[:first] || opts[:
|
387
|
+
opts[:first] || opts[:first_time] ||
|
388
|
+
opts[:first_at] || opts[:first_in] ||
|
389
|
+
0
|
372
390
|
self.last_at =
|
373
391
|
opts[:last] || opts[:last_at] || opts[:last_in]
|
374
392
|
end
|
375
393
|
|
376
394
|
def first_at=(first)
|
377
395
|
|
396
|
+
n = Time.now
|
397
|
+
first = n + 0.001 if first == :now || first == :immediately
|
398
|
+
|
378
399
|
@first_at = Rufus::Scheduler.parse_to_time(first)
|
379
400
|
|
380
401
|
raise ArgumentError.new(
|
381
402
|
"cannot set first[_at|_in] in the past: " +
|
382
403
|
"#{first.inspect} -> #{@first_at.inspect}"
|
383
|
-
) if first != 0 && @first_at <
|
404
|
+
) if first != 0 && @first_at < n
|
384
405
|
end
|
385
406
|
|
386
407
|
def last_at=(last)
|
data/out.txt
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
[:scheduled_at, 2014-01-22 22:21:21 +0900, 1390396881.344438]
|
2
|
+
[:in, 2014-01-22 22:21:21 +0900, 1390396881.6453865]
|
3
|
+
[:in, 2014-01-22 22:21:24 +0900, 1390396884.648807]
|
4
|
+
[:in, 2014-01-22 22:21:27 +0900, 1390396887.651686]
|
5
|
+
[:in, 2014-01-22 22:21:30 +0900, 1390396890.6571937]
|
6
|
+
[:in, 2014-01-22 22:21:33 +0900, 1390396893.661189]
|
7
|
+
[:in, 2014-01-22 22:21:36 +0900, 1390396896.6648037]
|
8
|
+
[:in, 2014-01-22 22:21:39 +0900, 1390396899.6698604]
|
data/spec/job_repeat_spec.rb
CHANGED
@@ -174,6 +174,29 @@ describe Rufus::Scheduler::RepeatJob do
|
|
174
174
|
|
175
175
|
}.should raise_error(ArgumentError)
|
176
176
|
end
|
177
|
+
|
178
|
+
context ':first_time => :now/:immediately' do
|
179
|
+
|
180
|
+
it 'schedules the first execution immediately' do
|
181
|
+
|
182
|
+
n = Time.now
|
183
|
+
ft = nil
|
184
|
+
|
185
|
+
job =
|
186
|
+
@scheduler.schedule_every '7s', :first => :now do
|
187
|
+
ft ||= Time.now
|
188
|
+
end
|
189
|
+
|
190
|
+
sleep 0.5
|
191
|
+
|
192
|
+
#p n.to_f
|
193
|
+
#p job.first_at.to_f
|
194
|
+
#p ft.to_f
|
195
|
+
|
196
|
+
job.first_at.should < n + 0.5
|
197
|
+
ft.should < job.first_at + @scheduler.frequency + 0.1
|
198
|
+
end
|
199
|
+
end
|
177
200
|
end
|
178
201
|
|
179
202
|
describe ':first/:first_in/:first_at => duration' do
|
data/spec/job_spec.rb
CHANGED
@@ -178,6 +178,70 @@ describe Rufus::Scheduler::Job do
|
|
178
178
|
end
|
179
179
|
end
|
180
180
|
|
181
|
+
describe '#call' do
|
182
|
+
|
183
|
+
it 'calls the job (like it were a proc)' do
|
184
|
+
|
185
|
+
counter = 0
|
186
|
+
|
187
|
+
job =
|
188
|
+
@scheduler.schedule_in('0.5s') do
|
189
|
+
counter = counter + 1
|
190
|
+
end
|
191
|
+
job.call
|
192
|
+
|
193
|
+
sleep 0.8
|
194
|
+
|
195
|
+
counter.should == 2
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe '#call(true)' do
|
200
|
+
|
201
|
+
it 'calls the job and let the scheduler handle errors' do
|
202
|
+
|
203
|
+
$err = nil
|
204
|
+
|
205
|
+
def @scheduler.on_error(job, err)
|
206
|
+
$err = "#{job.class} #{job.original} #{err.message}"
|
207
|
+
rescue
|
208
|
+
p $!
|
209
|
+
end
|
210
|
+
|
211
|
+
job =
|
212
|
+
@scheduler.schedule_in('1d') do
|
213
|
+
fail 'again'
|
214
|
+
end
|
215
|
+
|
216
|
+
job.call(true)
|
217
|
+
|
218
|
+
$err.should == 'Rufus::Scheduler::InJob 1d again'
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe '#call(false)' do
|
223
|
+
|
224
|
+
it 'calls the job and let errors slip through' do
|
225
|
+
|
226
|
+
job =
|
227
|
+
@scheduler.schedule_in('1d') do
|
228
|
+
fail 'fast'
|
229
|
+
end
|
230
|
+
|
231
|
+
begin
|
232
|
+
|
233
|
+
#job.call(false)
|
234
|
+
job.call # false is the default
|
235
|
+
|
236
|
+
false.should == true
|
237
|
+
|
238
|
+
rescue => ex
|
239
|
+
|
240
|
+
ex.message.should == 'fast'
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
181
245
|
context 'job-local variables' do
|
182
246
|
|
183
247
|
describe '#[]=' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-01-
|
12
|
+
date: 2014-01-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: tzinfo
|
@@ -98,12 +98,13 @@ files:
|
|
98
98
|
- CHANGELOG.txt
|
99
99
|
- TODO.txt
|
100
100
|
- LICENSE.txt
|
101
|
+
- out.txt
|
101
102
|
- CREDITS.txt
|
102
103
|
- README.md
|
103
104
|
homepage: http://github.com/jmettraux/rufus-scheduler
|
104
105
|
licenses:
|
105
106
|
- MIT
|
106
|
-
post_install_message: ! "\n***\n\nThanks for installing rufus-scheduler 3.0.
|
107
|
+
post_install_message: ! "\n***\n\nThanks for installing rufus-scheduler 3.0.5\n\nIt
|
107
108
|
might not be 100% compatible with rufus-scheduler 2.x.\n\nIf you encounter issues
|
108
109
|
with this new rufus-scheduler, especially\nif your app worked fine with previous
|
109
110
|
versions of it, you can\n\nA) Forget it and peg your Gemfile to rufus-scheduler
|