rufus-scheduler 3.5.2 → 3.6.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 +5 -5
- data/CHANGELOG.md +8 -0
- data/CREDITS.md +4 -0
- data/LICENSE.txt +1 -1
- data/README.md +36 -29
- data/lib/rufus/scheduler.rb +5 -2
- data/lib/rufus/scheduler/jobs.rb +37 -18
- data/rufus-scheduler.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 02a3bef52f292ce97e4918c53add3f0f6ba7a10c
|
|
4
|
+
data.tar.gz: '059fec2bf86103a66eb30be091fcd96f4b21abaf'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8282e8998f735291b30a5dfd8fc0b03ce5b2a5f19a38d747b197ae46b2b8324076af6583eb3c29a49273a066899871d2edd61f1628d6b9df583144a969095afd
|
|
7
|
+
data.tar.gz: 0d272804d8de32ba93f96b25e9d7be1a6493166c33865a9bfe6ca38ea848db43a89266818d9c0fec3cc37e4a8e83623f88c56566bdb59f2afd85f6c484b0dea6
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
# CHANGELOG.md
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
### rufus-scheduler 3.6.0 - released 2019-04-22
|
|
6
|
+
|
|
7
|
+
* Let Scheduler#cron fail if the cron string is invalid, gh-289
|
|
8
|
+
* Implement Job#next_times(count) for cron, every, and interval jobs
|
|
9
|
+
* Implement Job#next_times(count) for at and in jobs
|
|
10
|
+
* Stop fooling around and stick to https://semver.org
|
|
11
|
+
|
|
12
|
+
|
|
5
13
|
### rufus-scheduler 3.5.2 - released 2018-08-01
|
|
6
14
|
|
|
7
15
|
* Use Fugit::Cron#rough_frequency
|
data/CREDITS.md
CHANGED
|
@@ -4,6 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
## Contributors
|
|
6
6
|
|
|
7
|
+
* Darwin Wu https://github.com/dwaxe Rails initializer vs tests change
|
|
8
|
+
* Mike Karolow https://github.com/mike-yesware update Travis target Rubies
|
|
9
|
+
* Jack-Nie https://github.com/jack-nie gh-285 fix broken comment link
|
|
10
|
+
* Yechiel Kalmenson (https://github.com/achasveachas) README link fix
|
|
7
11
|
* Alex Coomans (https://github.com/drcapulet) gh-276 freq check pref improvement
|
|
8
12
|
* Vais Salikhov (https://github.com/vais) many document clarifications
|
|
9
13
|
* Wes McNamee (https://github.com/ghostsquad) let #schedule accept a CronLine
|
data/LICENSE.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
Copyright (c) 2005-
|
|
2
|
+
Copyright (c) 2005-2019, 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,8 +1,9 @@
|
|
|
1
1
|
|
|
2
2
|
# rufus-scheduler
|
|
3
3
|
|
|
4
|
-
[](
|
|
5
|
-
[](
|
|
4
|
+
[](https://travis-ci.org/jmettraux/rufus-scheduler)
|
|
5
|
+
[](https://badge.fury.io/rb/rufus-scheduler)
|
|
6
|
+
[](https://gitter.im/floraison/fugit?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
6
7
|
|
|
7
8
|
Job scheduler for Ruby (at, cron, in and every jobs).
|
|
8
9
|
|
|
@@ -58,6 +59,8 @@ end
|
|
|
58
59
|
# ...
|
|
59
60
|
```
|
|
60
61
|
|
|
62
|
+
Rufus-scheduler uses [fugit](https://github.com/floraison/fugit) for parsing time strings, [et-orbi](https://github.com/floraison/et-orbi) for pairing time and [tzinfo](https://github.com/tzinfo/tzinfo) timezones.
|
|
63
|
+
|
|
61
64
|
## non-features
|
|
62
65
|
|
|
63
66
|
Rufus-scheduler (out of the box) is an in-process, in-memory scheduler. It uses threads.
|
|
@@ -72,7 +75,7 @@ A rufus-scheduler instance will go on scheduling while it is present among the o
|
|
|
72
75
|
* [Whenever](https://github.com/javan/whenever) - let cron call back your Ruby code, trusted and reliable cron drives your schedule
|
|
73
76
|
* [Clockwork](https://github.com/Rykian/clockwork) - rufus-scheduler inspired gem
|
|
74
77
|
* [Crono](https://github.com/plashchynski/crono) - an in-Rails cron scheduler
|
|
75
|
-
* [PerfectSched](https://github.com/treasure-data/perfectsched) - highly available distributed cron built on [Sequel](
|
|
78
|
+
* [PerfectSched](https://github.com/treasure-data/perfectsched) - highly available distributed cron built on [Sequel](https://sequel.jeremyevans.net) and more
|
|
76
79
|
|
|
77
80
|
(please note: rufus-scheduler is not a cron replacement)
|
|
78
81
|
|
|
@@ -89,7 +92,7 @@ There is no EventMachine-based scheduler anymore.
|
|
|
89
92
|
I'll drive you right to the [tracks](#so-rails).
|
|
90
93
|
|
|
91
94
|
|
|
92
|
-
##
|
|
95
|
+
## notable changes:
|
|
93
96
|
|
|
94
97
|
* As said, no more EventMachine-based scheduler
|
|
95
98
|
* ```scheduler.every('100') {``` will schedule every 100 seconds (previously, it would have been 0.1s). This aligns rufus-scheduler with Ruby's ```sleep(100)```
|
|
@@ -108,26 +111,26 @@ So you need help. People can help you, but first help them help you, and don't w
|
|
|
108
111
|
|
|
109
112
|
"hello", "please" and "thanks" are not swear words.
|
|
110
113
|
|
|
111
|
-
Go read [how to report bugs effectively](
|
|
114
|
+
Go read [how to report bugs effectively](https://www.chiark.greenend.org.uk/~sgtatham/bugs.html), twice.
|
|
112
115
|
|
|
113
116
|
Update: [help_help.md](https://gist.github.com/jmettraux/310fed75f568fd731814) might help help you.
|
|
114
117
|
|
|
115
|
-
### on
|
|
118
|
+
### on Gitter
|
|
116
119
|
|
|
117
|
-
|
|
120
|
+
You can find help via chat over at [https://gitter.im/floraison/fugit](https://gitter.im/floraison/fugit). It's [fugit](https://github.com/floraison/fugit), [et-orbi](https://github.com/floraison/et-orbi), and rufus-scheduler combined chat room.
|
|
118
121
|
|
|
119
|
-
Please
|
|
122
|
+
Please be courteous.
|
|
120
123
|
|
|
121
124
|
### issues
|
|
122
125
|
|
|
123
|
-
Yes, issues can be reported in [rufus-scheduler issues](https://github.com/jmettraux/rufus-scheduler/issues), I'd actually prefer bugs in there. If there is nothing wrong with rufus-scheduler, a [Stack Overflow question](
|
|
126
|
+
Yes, issues can be reported in [rufus-scheduler issues](https://github.com/jmettraux/rufus-scheduler/issues), I'd actually prefer bugs in there. If there is nothing wrong with rufus-scheduler, a [Stack Overflow question](https://stackoverflow.com/questions/ask?tags=rufus-scheduler+ruby) is better.
|
|
124
127
|
|
|
125
128
|
### faq
|
|
126
129
|
|
|
127
|
-
* [It doesn't work...](
|
|
128
|
-
* [I want a refund](
|
|
129
|
-
* [Passenger and rufus-scheduler](
|
|
130
|
-
* [Passenger and rufus-scheduler (2)](
|
|
130
|
+
* [It doesn't work...](https://www.chiark.greenend.org.uk/~sgtatham/bugs.html)
|
|
131
|
+
* [I want a refund](https://blog.nodejitsu.com/getting-refunds-on-open-source-projects)
|
|
132
|
+
* [Passenger and rufus-scheduler](https://stackoverflow.com/questions/18108719/debugging-rufus-scheduler/18156180#18156180)
|
|
133
|
+
* [Passenger and rufus-scheduler (2)](https://stackoverflow.com/questions/21861387/rufus-cron-job-not-working-in-apache-passenger#answer-21868555)
|
|
131
134
|
* [Passenger in-depth spawn methods](https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/)
|
|
132
135
|
* [Passenger in-depth spawn methods (smart spawning)](https://www.phusionpassenger.com/library/indepth/ruby/spawn_methods/#smart-spawning-hooks)
|
|
133
136
|
* [The scheduler comes up when running the Rails console or a Rake task](https://github.com/jmettraux/rufus-scheduler#avoid-scheduling-when-running-the-ruby-on-rails-console)
|
|
@@ -687,6 +690,12 @@ The job keeps track of how long its work was in the `last_work_time` attribute.
|
|
|
687
690
|
|
|
688
691
|
The attribute `mean_work_time` contains a computed mean work time. It's recomputed after every run (if it's a repeat job).
|
|
689
692
|
|
|
693
|
+
### next_times(n)
|
|
694
|
+
|
|
695
|
+
Returns an array of `EtOrbi::EoTime` instances (Time instances with a designated time zone), listing the `n` next occurrences for this job.
|
|
696
|
+
|
|
697
|
+
Please note that for "interval" jobs, a mean work time is computed each time and it's used by this `#next_times(n)` method to approximate the next times beyond the immediate next time.
|
|
698
|
+
|
|
690
699
|
### unschedule
|
|
691
700
|
|
|
692
701
|
Unschedule the job, preventing it from firing again and removing it from the schedule. This doesn't prevent a running thread for this job to run until its end.
|
|
@@ -1231,7 +1240,7 @@ scheduler.max_work_threads += 10
|
|
|
1231
1240
|
## Rufus::Scheduler.singleton
|
|
1232
1241
|
|
|
1233
1242
|
Do not want to store a reference to your rufus-scheduler instance?
|
|
1234
|
-
Then ```Rufus::Scheduler.singleton``` can help, it returns a
|
|
1243
|
+
Then ```Rufus::Scheduler.singleton``` can help, it returns a singleton instance of the scheduler, initialized the first time this class method is called.
|
|
1235
1244
|
|
|
1236
1245
|
```ruby
|
|
1237
1246
|
Rufus::Scheduler.singleton.every '10s' { puts "hello, world!" }
|
|
@@ -1290,7 +1299,7 @@ class ZookeptScheduler < Rufus::Scheduler
|
|
|
1290
1299
|
end
|
|
1291
1300
|
```
|
|
1292
1301
|
|
|
1293
|
-
This uses a [zookeeper](
|
|
1302
|
+
This uses a [zookeeper](https://zookeeper.apache.org/) to make sure only one scheduler in a group of distributed schedulers runs.
|
|
1294
1303
|
|
|
1295
1304
|
The methods #lock and #unlock are overridden and #confirm_lock is provided,
|
|
1296
1305
|
to make sure that the lock is still valid.
|
|
@@ -1314,6 +1323,8 @@ Warning: you may think you're heading towards "high availability" by using a tri
|
|
|
1314
1323
|
|
|
1315
1324
|
## parsing cronlines and time strings
|
|
1316
1325
|
|
|
1326
|
+
(Please note that [fugit](https://github.com/floraison/fugit) does the heavy-lifting parsing work for rufus-scheduler).
|
|
1327
|
+
|
|
1317
1328
|
Rufus::Scheduler provides a class method ```.parse``` to parse time durations and cron strings. It's what it's using when receiving schedules. One can use it directly (no need to instantiate a Scheduler).
|
|
1318
1329
|
|
|
1319
1330
|
```ruby
|
|
@@ -1550,9 +1561,9 @@ The rufus-scheduler singleton is instantiated in the ```config/initializers/sche
|
|
|
1550
1561
|
|
|
1551
1562
|
### avoid scheduling when running the Ruby on Rails console
|
|
1552
1563
|
|
|
1553
|
-
(Written in reply to https://github.com/jmettraux/rufus-scheduler/issues/186
|
|
1564
|
+
(Written in reply to [gh-186](https://github.com/jmettraux/rufus-scheduler/issues/186))
|
|
1554
1565
|
|
|
1555
|
-
If you don't want rufus-scheduler to
|
|
1566
|
+
If you don't want rufus-scheduler to trigger anything while running the Ruby on Rails console, running for tests/specs, or running from a Rake task, you can insert a conditional return statement before jobs are added to the scheduler instance:
|
|
1556
1567
|
|
|
1557
1568
|
```ruby
|
|
1558
1569
|
#
|
|
@@ -1562,21 +1573,17 @@ require 'rufus-scheduler'
|
|
|
1562
1573
|
|
|
1563
1574
|
s = Rufus::Scheduler.singleton
|
|
1564
1575
|
|
|
1576
|
+
return if defined?(Rails::Console) || Rails.env.test? || File.split($0).last == 'rake'
|
|
1565
1577
|
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
# only schedule when not running from the Ruby on Rails console
|
|
1569
|
-
# or from a rake task
|
|
1578
|
+
# do not schedule when Rails is run from its console, for a test/spec, or
|
|
1579
|
+
# from a Rake task
|
|
1570
1580
|
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
Rails.logger.flush
|
|
1575
|
-
end
|
|
1581
|
+
s.every '1m' do
|
|
1582
|
+
Rails.logger.info "hello, it's #{Time.now}"
|
|
1583
|
+
Rails.logger.flush
|
|
1576
1584
|
end
|
|
1577
1585
|
```
|
|
1578
1586
|
|
|
1579
|
-
It should work for Ruby on Rails 3 and 4.
|
|
1580
1587
|
|
|
1581
1588
|
### rails server -d
|
|
1582
1589
|
|
|
@@ -1588,8 +1595,8 @@ I avoid running `-d` in development mode and bother about daemonizing only for p
|
|
|
1588
1595
|
|
|
1589
1596
|
These are two well crafted articles on process daemonization, please read them:
|
|
1590
1597
|
|
|
1591
|
-
*
|
|
1592
|
-
*
|
|
1598
|
+
* https://www.mikeperham.com/2014/09/22/dont-daemonize-your-daemons/
|
|
1599
|
+
* https://www.mikeperham.com/2014/07/07/use-runit/
|
|
1593
1600
|
|
|
1594
1601
|
If, anyway, you need something like `rails server -d`, why not try `bundle exec unicorn -D` instead? In my (limited) experience, it worked out of the box (well, had to add `gem 'unicorn'` to `Gemfile` first).
|
|
1595
1602
|
|
data/lib/rufus/scheduler.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Rufus
|
|
|
11
11
|
|
|
12
12
|
class Scheduler
|
|
13
13
|
|
|
14
|
-
VERSION = '3.
|
|
14
|
+
VERSION = '3.6.0'
|
|
15
15
|
|
|
16
16
|
EoTime = ::EtOrbi::EoTime
|
|
17
17
|
|
|
@@ -115,7 +115,10 @@ module Rufus
|
|
|
115
115
|
@started_at = nil
|
|
116
116
|
|
|
117
117
|
#jobs.each { |j| j.unschedule }
|
|
118
|
-
#
|
|
118
|
+
#
|
|
119
|
+
# which provokes https://github.com/jmettraux/rufus-scheduler/issues/98
|
|
120
|
+
# using the following instead:
|
|
121
|
+
#
|
|
119
122
|
@jobs.array.each { |j| j.unschedule }
|
|
120
123
|
|
|
121
124
|
@work_queue.clear
|
data/lib/rufus/scheduler/jobs.rb
CHANGED
|
@@ -177,6 +177,11 @@ module Rufus
|
|
|
177
177
|
#
|
|
178
178
|
# might be necessary at some point
|
|
179
179
|
|
|
180
|
+
def next_times(count)
|
|
181
|
+
|
|
182
|
+
next_time ? [ next_time ] : []
|
|
183
|
+
end
|
|
184
|
+
|
|
180
185
|
# Calls the callable (usually a block) wrapped in this Job instance.
|
|
181
186
|
#
|
|
182
187
|
# Warning: error rescueing is the responsibity of the caller.
|
|
@@ -520,6 +525,20 @@ module Rufus
|
|
|
520
525
|
|
|
521
526
|
a
|
|
522
527
|
end
|
|
528
|
+
|
|
529
|
+
# Starting from now, returns the {count} next occurences
|
|
530
|
+
# (EtOrbi::EoTime instances) for this job.
|
|
531
|
+
#
|
|
532
|
+
# Warning, for IntervalJob, the @mean_work_time is used since
|
|
533
|
+
# "interval" works from the end of a job to its next trigger
|
|
534
|
+
# (not from one trigger to the next, as for "cron" and "every").
|
|
535
|
+
#
|
|
536
|
+
def next_times(count)
|
|
537
|
+
|
|
538
|
+
(count - 1).times.inject([ next_time ]) { |a|
|
|
539
|
+
a << next_time_from(a.last)
|
|
540
|
+
a }
|
|
541
|
+
end
|
|
523
542
|
end
|
|
524
543
|
|
|
525
544
|
#
|
|
@@ -559,6 +578,11 @@ module Rufus
|
|
|
559
578
|
) if @frequency < @scheduler.frequency
|
|
560
579
|
end
|
|
561
580
|
|
|
581
|
+
def next_time_from(time)
|
|
582
|
+
|
|
583
|
+
time + @frequency
|
|
584
|
+
end
|
|
585
|
+
|
|
562
586
|
protected
|
|
563
587
|
|
|
564
588
|
def set_next_time(trigger_time, is_post=false)
|
|
@@ -574,11 +598,6 @@ module Rufus
|
|
|
574
598
|
(@next_time || n) + @frequency
|
|
575
599
|
end
|
|
576
600
|
end
|
|
577
|
-
|
|
578
|
-
def next_time_from(time)
|
|
579
|
-
|
|
580
|
-
time + @frequency
|
|
581
|
-
end
|
|
582
601
|
end
|
|
583
602
|
|
|
584
603
|
class IntervalJob < EvInJob
|
|
@@ -599,6 +618,11 @@ module Rufus
|
|
|
599
618
|
set_next_time(nil)
|
|
600
619
|
end
|
|
601
620
|
|
|
621
|
+
def next_time_from(time)
|
|
622
|
+
|
|
623
|
+
time + @mean_work_time + @interval
|
|
624
|
+
end
|
|
625
|
+
|
|
602
626
|
protected
|
|
603
627
|
|
|
604
628
|
def set_next_time(trigger_time, is_post=false)
|
|
@@ -616,11 +640,6 @@ module Rufus
|
|
|
616
640
|
false
|
|
617
641
|
end
|
|
618
642
|
end
|
|
619
|
-
|
|
620
|
-
def next_time_from(time)
|
|
621
|
-
|
|
622
|
-
time + @mean_work_time + @interval
|
|
623
|
-
end
|
|
624
643
|
end
|
|
625
644
|
|
|
626
645
|
class CronJob < RepeatJob
|
|
@@ -631,7 +650,7 @@ module Rufus
|
|
|
631
650
|
|
|
632
651
|
super(scheduler, cronline, opts, block)
|
|
633
652
|
|
|
634
|
-
@cron_line = opts[:_t] || ::Fugit::Cron.
|
|
653
|
+
@cron_line = opts[:_t] || ::Fugit::Cron.do_parse(cronline)
|
|
635
654
|
|
|
636
655
|
set_next_time(nil)
|
|
637
656
|
end
|
|
@@ -661,13 +680,6 @@ module Rufus
|
|
|
661
680
|
@cron_line.rough_frequency
|
|
662
681
|
end
|
|
663
682
|
|
|
664
|
-
protected
|
|
665
|
-
|
|
666
|
-
def set_next_time(trigger_time, is_post=false)
|
|
667
|
-
|
|
668
|
-
@next_time = next_time_from(trigger_time || Time.now)
|
|
669
|
-
end
|
|
670
|
-
|
|
671
683
|
def next_time_from(time)
|
|
672
684
|
|
|
673
685
|
if @first_at == nil || @first_at <= time
|
|
@@ -676,6 +688,13 @@ module Rufus
|
|
|
676
688
|
@first_at
|
|
677
689
|
end
|
|
678
690
|
end
|
|
691
|
+
|
|
692
|
+
protected
|
|
693
|
+
|
|
694
|
+
def set_next_time(trigger_time, is_post=false)
|
|
695
|
+
|
|
696
|
+
@next_time = next_time_from(trigger_time || Time.now)
|
|
697
|
+
end
|
|
679
698
|
end
|
|
680
699
|
end
|
|
681
700
|
end
|
data/rufus-scheduler.gemspec
CHANGED
|
@@ -40,7 +40,7 @@ Job scheduler for Ruby (at, cron, in and every jobs). Not a replacement for cron
|
|
|
40
40
|
|
|
41
41
|
s.required_ruby_version = '>= 1.9'
|
|
42
42
|
|
|
43
|
-
s.add_runtime_dependency 'fugit', '~> 1.1', '>= 1.1.
|
|
43
|
+
s.add_runtime_dependency 'fugit', '~> 1.1', '>= 1.1.6'
|
|
44
44
|
|
|
45
45
|
s.add_development_dependency 'rspec', '~> 3.7'
|
|
46
46
|
s.add_development_dependency 'chronic', '~> 0.10'
|
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.6.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: 2019-04-22 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: fugit
|
|
@@ -19,7 +19,7 @@ dependencies:
|
|
|
19
19
|
version: '1.1'
|
|
20
20
|
- - ">="
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: 1.1.
|
|
22
|
+
version: 1.1.6
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -29,7 +29,7 @@ dependencies:
|
|
|
29
29
|
version: '1.1'
|
|
30
30
|
- - ">="
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 1.1.
|
|
32
|
+
version: 1.1.6
|
|
33
33
|
- !ruby/object:Gem::Dependency
|
|
34
34
|
name: rspec
|
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -102,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
102
102
|
version: '0'
|
|
103
103
|
requirements: []
|
|
104
104
|
rubyforge_project: rufus
|
|
105
|
-
rubygems_version: 2.
|
|
105
|
+
rubygems_version: 2.6.14.3
|
|
106
106
|
signing_key:
|
|
107
107
|
specification_version: 4
|
|
108
108
|
summary: job scheduler for Ruby (at, cron, in and every jobs)
|