rufus-scheduler 3.7.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/LICENSE.txt +1 -1
- data/README.md +64 -46
- data/lib/rufus/scheduler.rb +2 -1
- data/lib/rufus/scheduler/jobs_core.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 86f0ae4ebefa9cf941f66efb56041515eea96cb5105289d9f0f54899841cffc6
|
4
|
+
data.tar.gz: 9e6d1422b91536aa56cc2cdb627f3c88e21748c8e8734ba2eb929a46912f303e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45667cceb3f382ac71b7158d2884fbde21c9ac6f3027889a1dd8b7fd855bd014b35a1a4180b93118552aa7e6e08df061259113b1a5ce86f4e892a4b2f8c0436e
|
7
|
+
data.tar.gz: 9ef9d0926f33bacdb0c2b8727b801d861db960ba4b6efac28642ea27e578c1de60a6b1b144217cace6c17de759100b0229c42ba79bb9db4b40527c1e8cdac8e4
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Copyright (c) 2005-
|
2
|
+
Copyright (c) 2005-2021, 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
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
|
2
2
|
# rufus-scheduler
|
3
3
|
|
4
|
-
[![
|
4
|
+
[![tests](https://github.com/jmettraux/rufus-scheduler/workflows/test/badge.svg)](https://github.com/jmettraux/rufus-scheduler/actions)
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/rufus-scheduler.svg)](https://badge.fury.io/rb/rufus-scheduler)
|
6
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)
|
7
7
|
|
@@ -223,7 +223,7 @@ job =
|
|
223
223
|
# also
|
224
224
|
|
225
225
|
job =
|
226
|
-
scheduler.in '10d', :
|
226
|
+
scheduler.in '10d', job: true do
|
227
227
|
# ...
|
228
228
|
end
|
229
229
|
```
|
@@ -378,7 +378,7 @@ While paused, the scheduler still accepts schedules, but no schedule will get tr
|
|
378
378
|
|
379
379
|
## job options
|
380
380
|
|
381
|
-
### :
|
381
|
+
### name: string
|
382
382
|
|
383
383
|
Sets the name of the job.
|
384
384
|
|
@@ -395,23 +395,23 @@ job1 =
|
|
395
395
|
job1.name = 'Beowulf'
|
396
396
|
```
|
397
397
|
|
398
|
-
### :
|
398
|
+
### blocking: true
|
399
399
|
|
400
|
-
By default, jobs are triggered in their own, new threads. When
|
400
|
+
By default, jobs are triggered in their own, new threads. When `blocking: true`, the job is triggered in the scheduler thread (a new thread is not created). Yes, while a blocking job is running, the scheduler is not scheduling.
|
401
401
|
|
402
|
-
### :
|
402
|
+
### overlap: false
|
403
403
|
|
404
404
|
Since, by default, jobs are triggered in their own new threads, job instances might overlap. For example, a job that takes 10 minutes and is scheduled every 7 minutes will have overlaps.
|
405
405
|
|
406
|
-
To prevent overlap, one can set
|
406
|
+
To prevent overlap, one can set `overlap: false`. Such a job will not trigger if one of its instances is already running.
|
407
407
|
|
408
408
|
The `:overlap` option is considered before the `:mutex` option when the scheduler is reviewing jobs for triggering.
|
409
409
|
|
410
|
-
### :
|
410
|
+
### mutex: mutex_instance / mutex_name / array of mutexes
|
411
411
|
|
412
412
|
When a job with a mutex triggers, the job's block is executed with the mutex around it, preventing other jobs with the same mutex from entering (it makes the other jobs wait until it exits the mutex).
|
413
413
|
|
414
|
-
This is different from
|
414
|
+
This is different from `overlap: false`, which is, first, limited to instances of the same job, and, second, doesn't make the incoming job instance block/wait but give up.
|
415
415
|
|
416
416
|
`:mutex` accepts a mutex instance or a mutex name (String). It also accept an array of mutex names / mutex instances. It allows for complex relations between jobs.
|
417
417
|
|
@@ -421,12 +421,12 @@ Note: creating lots of different mutexes is OK. Rufus-scheduler will place them
|
|
421
421
|
|
422
422
|
The `:overlap` option is considered before the `:mutex` option when the scheduler is reviewing jobs for triggering.
|
423
423
|
|
424
|
-
### :
|
424
|
+
### timeout: duration or point in time
|
425
425
|
|
426
426
|
It's OK to specify a timeout when scheduling some work. After the time specified, it gets interrupted via a Rufus::Scheduler::TimeoutError.
|
427
427
|
|
428
428
|
```ruby
|
429
|
-
scheduler.in '10d', :
|
429
|
+
scheduler.in '10d', timeout: '1d' do
|
430
430
|
begin
|
431
431
|
# ... do something
|
432
432
|
rescue Rufus::Scheduler::TimeoutError
|
@@ -447,15 +447,15 @@ In the case of an "every" job, this will be the first time (modulo the scheduler
|
|
447
447
|
For a "cron" job as well, the :first will point to the first time the job has to trigger, the following trigger times are then determined by the cron string.
|
448
448
|
|
449
449
|
```ruby
|
450
|
-
scheduler.every '2d', :
|
450
|
+
scheduler.every '2d', first_at: Time.now + 10 * 3600 do
|
451
451
|
# ... every two days, but start in 10 hours
|
452
452
|
end
|
453
453
|
|
454
|
-
scheduler.every '2d', :
|
454
|
+
scheduler.every '2d', first_in: '10h' do
|
455
455
|
# ... every two days, but start in 10 hours
|
456
456
|
end
|
457
457
|
|
458
|
-
scheduler.cron '00 14 * * *', :
|
458
|
+
scheduler.cron '00 14 * * *', first_in: '3d' do
|
459
459
|
# ... every day at 14h00, but start after 3 * 24 hours
|
460
460
|
end
|
461
461
|
```
|
@@ -477,7 +477,7 @@ s = Rufus::Scheduler.new
|
|
477
477
|
|
478
478
|
n = Time.now; p [ :scheduled_at, n, n.to_f ]
|
479
479
|
|
480
|
-
s.every '3s', :
|
480
|
+
s.every '3s', first: :now do
|
481
481
|
n = Time.now; p [ :in, n, n.to_f ]
|
482
482
|
end
|
483
483
|
|
@@ -502,15 +502,15 @@ This option is for repeat jobs (cron / every) only.
|
|
502
502
|
It indicates the point in time after which the job should unschedule itself.
|
503
503
|
|
504
504
|
```ruby
|
505
|
-
scheduler.cron '5 23 * * *', :
|
505
|
+
scheduler.cron '5 23 * * *', last_in: '10d' do
|
506
506
|
# ... do something every evening at 23:05 for 10 days
|
507
507
|
end
|
508
508
|
|
509
|
-
scheduler.every '10m', :
|
509
|
+
scheduler.every '10m', last_at: Time.now + 10 * 3600 do
|
510
510
|
# ... do something every 10 minutes for 10 hours
|
511
511
|
end
|
512
512
|
|
513
|
-
scheduler.every '10m', :
|
513
|
+
scheduler.every '10m', last_in: 10 * 3600 do
|
514
514
|
# ... do something every 10 minutes for 10 hours
|
515
515
|
end
|
516
516
|
```
|
@@ -525,16 +525,16 @@ job.last_at = Rufus::Scheduler.parse('2029-12-12')
|
|
525
525
|
# set the last bound
|
526
526
|
```
|
527
527
|
|
528
|
-
### :
|
528
|
+
### times: nb of times (before auto-unscheduling)
|
529
529
|
|
530
530
|
One can tell how many times a repeat job (CronJob or EveryJob) is to execute before unscheduling by itself.
|
531
531
|
|
532
532
|
```ruby
|
533
|
-
scheduler.every '2d', :
|
533
|
+
scheduler.every '2d', times: 10 do
|
534
534
|
# ... do something every two days, but not more than 10 times
|
535
535
|
end
|
536
536
|
|
537
|
-
scheduler.cron '0 23 * * *', :
|
537
|
+
scheduler.cron '0 23 * * *', times: 31 do
|
538
538
|
# ... do something every day at 23:00 but do it no more than 31 times
|
539
539
|
end
|
540
540
|
```
|
@@ -542,7 +542,7 @@ end
|
|
542
542
|
It's OK to assign nil to :times to make sure the repeat job is not limited. It's useful when the :times is determined at scheduling time.
|
543
543
|
|
544
544
|
```ruby
|
545
|
-
scheduler.cron '0 23 * * *', :
|
545
|
+
scheduler.cron '0 23 * * *', times: (nolimit ? nil : 10) do
|
546
546
|
# ...
|
547
547
|
end
|
548
548
|
```
|
@@ -564,7 +564,7 @@ job.times = 10
|
|
564
564
|
|
565
565
|
## Job methods
|
566
566
|
|
567
|
-
When calling a schedule method, the id (String) of the job is returned. Longer schedule methods return Job instances directly. Calling the shorter schedule methods with the :
|
567
|
+
When calling a schedule method, the id (String) of the job is returned. Longer schedule methods return Job instances directly. Calling the shorter schedule methods with the `job: true` also returns Job instances instead of Job ids (Strings).
|
568
568
|
|
569
569
|
```ruby
|
570
570
|
require 'rufus-scheduler'
|
@@ -582,7 +582,7 @@ When calling a schedule method, the id (String) of the job is returned. Longer s
|
|
582
582
|
end
|
583
583
|
|
584
584
|
job =
|
585
|
-
scheduler.in '1w', :
|
585
|
+
scheduler.in '1w', job: true do
|
586
586
|
# ...
|
587
587
|
end
|
588
588
|
```
|
@@ -608,7 +608,7 @@ Returns the scheduler instance itself.
|
|
608
608
|
Returns the options passed at the Job creation.
|
609
609
|
|
610
610
|
```ruby
|
611
|
-
job = scheduler.schedule_in('10d', :
|
611
|
+
job = scheduler.schedule_in('10d', tag: 'hello') do; end
|
612
612
|
job.opts
|
613
613
|
# => { :tag => 'hello' }
|
614
614
|
```
|
@@ -618,7 +618,7 @@ job.opts
|
|
618
618
|
Returns the original schedule.
|
619
619
|
|
620
620
|
```ruby
|
621
|
-
job = scheduler.schedule_in('10d', :
|
621
|
+
job = scheduler.schedule_in('10d', tag: 'hello') do; end
|
622
622
|
job.original
|
623
623
|
# => '10d'
|
624
624
|
```
|
@@ -665,12 +665,30 @@ job.callable
|
|
665
665
|
# => #<MyHandler:0x0000000163ae88 @counter=0>
|
666
666
|
```
|
667
667
|
|
668
|
+
### source_location
|
669
|
+
|
670
|
+
Added to rufus-scheduler 3.8.0.
|
671
|
+
|
672
|
+
Returns the array `[ 'path/to/file.rb', 123 ]` like `Proc#source_location` does.
|
673
|
+
|
674
|
+
```ruby
|
675
|
+
require 'rufus-scheduler'
|
676
|
+
|
677
|
+
scheduler = Rufus::Scheduler.new
|
678
|
+
|
679
|
+
job = scheduler.schedule_every('2h') { p Time.now }
|
680
|
+
|
681
|
+
p job.source_location
|
682
|
+
# ==> [ '/home/jmettraux/rufus-scheduler/test.rb', 6 ]
|
683
|
+
|
684
|
+
```
|
685
|
+
|
668
686
|
### scheduled_at
|
669
687
|
|
670
688
|
Returns the Time instance when the job got created.
|
671
689
|
|
672
690
|
```ruby
|
673
|
-
job = scheduler.schedule_in('10d', :
|
691
|
+
job = scheduler.schedule_in('10d', tag: 'hello') do; end
|
674
692
|
job.scheduled_at
|
675
693
|
# => 2013-07-17 23:48:54 +0900
|
676
694
|
```
|
@@ -773,7 +791,7 @@ job = scheduler.schedule_in('10d') do; end
|
|
773
791
|
job.tags
|
774
792
|
# => []
|
775
793
|
|
776
|
-
job = scheduler.schedule_in('10d', :
|
794
|
+
job = scheduler.schedule_in('10d', tag: 'hello') do; end
|
777
795
|
job.tags
|
778
796
|
# => [ 'hello' ]
|
779
797
|
```
|
@@ -958,24 +976,24 @@ Here is an example:
|
|
958
976
|
scheduler.at_jobs.each(&:unschedule)
|
959
977
|
```
|
960
978
|
|
961
|
-
### Scheduler#jobs(:
|
979
|
+
### Scheduler#jobs(tag: / tags: x)
|
962
980
|
|
963
981
|
When scheduling a job, one can specify one or more tags attached to the job. These can be used to look up the job later on.
|
964
982
|
|
965
983
|
```ruby
|
966
|
-
scheduler.in '10d', :
|
984
|
+
scheduler.in '10d', tag: 'main_process' do
|
967
985
|
# ...
|
968
986
|
end
|
969
|
-
scheduler.in '10d', :
|
987
|
+
scheduler.in '10d', tags: [ 'main_process', 'side_dish' ] do
|
970
988
|
# ...
|
971
989
|
end
|
972
990
|
|
973
991
|
# ...
|
974
992
|
|
975
|
-
jobs = scheduler.jobs(:
|
993
|
+
jobs = scheduler.jobs(tag: 'main_process')
|
976
994
|
# find all the jobs with the 'main_process' tag
|
977
995
|
|
978
|
-
jobs = scheduler.jobs(:
|
996
|
+
jobs = scheduler.jobs(tags: [ 'main_process', 'side_dish' ]
|
979
997
|
# find all the jobs with the 'main_process' AND 'side_dish' tags
|
980
998
|
```
|
981
999
|
|
@@ -1040,7 +1058,7 @@ Lists the work threads associated with the scheduler. The query option defaults
|
|
1040
1058
|
* :active : all the work threads currently running a Job
|
1041
1059
|
* :vacant : all the work threads currently not running a Job
|
1042
1060
|
|
1043
|
-
Note that the main schedule thread will be returned if it is currently running a Job (ie one of those :
|
1061
|
+
Note that the main schedule thread will be returned if it is currently running a Job (ie one of those `blocking: true` jobs).
|
1044
1062
|
|
1045
1063
|
### Scheduler#scheduled?(job_or_job_id)
|
1046
1064
|
|
@@ -1048,7 +1066,7 @@ Returns true if the arg is a currently scheduled job (see Job#scheduled?).
|
|
1048
1066
|
|
1049
1067
|
### Scheduler#occurrences(time0, time1)
|
1050
1068
|
|
1051
|
-
Returns a hash
|
1069
|
+
Returns a hash `{ job => [ t0, t1, ... ] }` mapping jobs to their potential trigger time within the `[ time0, time1 ]` span.
|
1052
1070
|
|
1053
1071
|
Please note that, for interval jobs, the ```#mean_work_time``` is used, so the result is only a prediction.
|
1054
1072
|
|
@@ -1205,23 +1223,23 @@ By default, rufus-scheduler sleeps 0.300 second between every step. At each step
|
|
1205
1223
|
The :frequency option lets you change that 0.300 second to something else.
|
1206
1224
|
|
1207
1225
|
```ruby
|
1208
|
-
scheduler = Rufus::Scheduler.new(:
|
1226
|
+
scheduler = Rufus::Scheduler.new(frequency: 5)
|
1209
1227
|
```
|
1210
1228
|
|
1211
1229
|
It's OK to use a time string to specify the frequency.
|
1212
1230
|
|
1213
1231
|
```ruby
|
1214
|
-
scheduler = Rufus::Scheduler.new(:
|
1232
|
+
scheduler = Rufus::Scheduler.new(frequency: '2h10m')
|
1215
1233
|
# this scheduler will sleep 2 hours and 10 minutes between every "step"
|
1216
1234
|
```
|
1217
1235
|
|
1218
1236
|
Use with care.
|
1219
1237
|
|
1220
|
-
### :
|
1238
|
+
### lockfile: "mylockfile.txt"
|
1221
1239
|
|
1222
1240
|
This feature only works on OSes that support the flock (man 2 flock) call.
|
1223
1241
|
|
1224
|
-
Starting the scheduler with
|
1242
|
+
Starting the scheduler with ```lockfile: '.rufus-scheduler.lock'``` will make the scheduler attempt to create and lock the file ```.rufus-scheduler.lock``` in the current working directory. If that fails, the scheduler will not start.
|
1225
1243
|
|
1226
1244
|
The idea is to guarantee only one scheduler (in a group of schedulers sharing the same lockfile) is running.
|
1227
1245
|
|
@@ -1250,7 +1268,7 @@ class HostLock
|
|
1250
1268
|
end
|
1251
1269
|
|
1252
1270
|
scheduler =
|
1253
|
-
Rufus::Scheduler.new(:
|
1271
|
+
Rufus::Scheduler.new(scheduler_lock: HostLock.new('coffee.example.com'))
|
1254
1272
|
```
|
1255
1273
|
|
1256
1274
|
By default, the scheduler_lock is an instance of `Rufus::Scheduler::NullLock`, with a `#lock` that returns true.
|
@@ -1273,7 +1291,7 @@ class PingLock
|
|
1273
1291
|
end
|
1274
1292
|
|
1275
1293
|
scheduler =
|
1276
|
-
Rufus::Scheduler.new(:
|
1294
|
+
Rufus::Scheduler.new(trigger_lock: PingLock.new('main.example.com'))
|
1277
1295
|
```
|
1278
1296
|
|
1279
1297
|
By default, the trigger_lock is an instance of `Rufus::Scheduler::NullLock`, with a `#lock` that always returns true.
|
@@ -1287,7 +1305,7 @@ In rufus-scheduler 2.x, by default, each job triggering received its own, brand
|
|
1287
1305
|
One can set this maximum value when starting the scheduler.
|
1288
1306
|
|
1289
1307
|
```ruby
|
1290
|
-
scheduler = Rufus::Scheduler.new(:
|
1308
|
+
scheduler = Rufus::Scheduler.new(max_work_threads: 77)
|
1291
1309
|
```
|
1292
1310
|
|
1293
1311
|
It's OK to increase the :max_work_threads of a running scheduler.
|
@@ -1309,8 +1327,8 @@ Rufus::Scheduler.singleton.every '10s' { puts "hello, world!" }
|
|
1309
1327
|
It's OK to pass initialization arguments (like :frequency or :max_work_threads) but they will only be taken into account the first time ```.singleton``` is called.
|
1310
1328
|
|
1311
1329
|
```ruby
|
1312
|
-
Rufus::Scheduler.singleton(:
|
1313
|
-
Rufus::Scheduler.singleton(:
|
1330
|
+
Rufus::Scheduler.singleton(max_work_threads: 77)
|
1331
|
+
Rufus::Scheduler.singleton(max_work_threads: 277) # no effect
|
1314
1332
|
```
|
1315
1333
|
|
1316
1334
|
The ```.s``` is a shortcut for ```.singleton```.
|
@@ -1427,7 +1445,7 @@ Rufus::Scheduler.to_duration_hash(60)
|
|
1427
1445
|
Rufus::Scheduler.to_duration_hash(62.127)
|
1428
1446
|
# => { :m => 1, :s => 2, :ms => 127 }
|
1429
1447
|
|
1430
|
-
Rufus::Scheduler.to_duration_hash(62.127, :
|
1448
|
+
Rufus::Scheduler.to_duration_hash(62.127, drop_seconds: true)
|
1431
1449
|
# => { :m => 1 }
|
1432
1450
|
```
|
1433
1451
|
|
@@ -1610,7 +1628,7 @@ class ScheController < ApplicationController
|
|
1610
1628
|
Rails.logger.info "time flies, it's now #{Time.now}"
|
1611
1629
|
end
|
1612
1630
|
|
1613
|
-
render :
|
1631
|
+
render text: "scheduled job #{job_id}"
|
1614
1632
|
end
|
1615
1633
|
end
|
1616
1634
|
```
|
data/lib/rufus/scheduler.rb
CHANGED
@@ -9,7 +9,7 @@ module Rufus; end
|
|
9
9
|
|
10
10
|
class Rufus::Scheduler
|
11
11
|
|
12
|
-
VERSION = '3.
|
12
|
+
VERSION = '3.8.0'
|
13
13
|
|
14
14
|
EoTime = ::EtOrbi::EoTime
|
15
15
|
|
@@ -445,6 +445,7 @@ class Rufus::Scheduler
|
|
445
445
|
stderr.puts("{ #{pre} rufus-scheduler intercepted an error:")
|
446
446
|
stderr.puts(" #{pre} job:")
|
447
447
|
stderr.puts(" #{pre} #{job.class} #{job.original.inspect} #{job.opts.inspect}")
|
448
|
+
stderr.puts(" #{pre} #{job.source_location.inspect}")
|
448
449
|
# TODO: eventually use a Job#detail or something like that
|
449
450
|
stderr.puts(" #{pre} error:")
|
450
451
|
stderr.puts(" #{pre} #{err.object_id}")
|
@@ -97,6 +97,12 @@ class Rufus::Scheduler::Job
|
|
97
97
|
|
98
98
|
alias job_id id
|
99
99
|
|
100
|
+
def source_location
|
101
|
+
|
102
|
+
@callable.source_location
|
103
|
+
end
|
104
|
+
alias location source_location
|
105
|
+
|
100
106
|
# Will fail with an ArgumentError if the job frequency is higher than
|
101
107
|
# the scheduler frequency.
|
102
108
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Mettraux
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fugit
|