ruby-clock 2.0.0.beta8 → 2.0.0.beta10
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 +4 -4
- data/CHANGELOG.md +9 -5
- data/README.md +51 -7
- data/example-app/Clockfile +1 -1
- data/example-app/Gemfile +1 -0
- data/exe/clock +59 -16
- data/lib/ruby-clock/version.rb +1 -1
- data/lib/rufus_monkeypatch.rb +7 -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: 0f773f1b873c6048b24cb6c78769c809fd3008c0316463071633086aa572f853
|
|
4
|
+
data.tar.gz: 28de0953617822f2473cecebdac1ab308420231670073db0d4458d89d527e3ee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e4d94f375285033a0ca49ed535b29f0768adac1efa83f4c63a67090f866aa2a1f72b4a0159c746d99bf765c8c5b7f308daff090be0e2b671518d8fe67cf3b63e
|
|
7
|
+
data.tar.gz: 693519be98311aff6e24aae1c61cf908f710049a6854886264f100dc844f8436b3ba58f0ab1bd9b6d6a5bf3f5916383d744ce9390dbb582bdd70f4c6dab03936
|
data/CHANGELOG.md
CHANGED
|
@@ -5,30 +5,33 @@
|
|
|
5
5
|
is implemented is now compatible with both rails 6 and 7
|
|
6
6
|
* RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS value is logged when starting
|
|
7
7
|
* DSL methods are now at the top-level namespace (`schedule.every` → `every`, `schedule.cron` → `cron`)
|
|
8
|
-
* Error handler definition is now at the top-level namespace (`def schedule.on_error` → `on_error do`)
|
|
9
8
|
* Around callbacks now have a top-level namespace method. `def schedule.around_trigger` → `around_action do`
|
|
10
9
|
* Multiple around callbacks can be consecutively assigned - no need to put all behavior into one method
|
|
10
|
+
* Error handler definition is now at the top-level namespace (`def schedule.on_error` → `on_error do`)
|
|
11
11
|
* Errors encountered when loading Clockfile (such as incorrect cron syntax)
|
|
12
12
|
will be reported to the error handler
|
|
13
13
|
* The automatic identifier generator will now ignore `}` and `end` lines
|
|
14
|
-
* posix-spawn is no longer used. In ruby 3, native `Process.spawn` is more performant. See
|
|
14
|
+
* posix-spawn is no longer used. In ruby ~3~ 2.2, native `Process.spawn` is more performant. See
|
|
15
15
|
[posix-spawn#90](https://github.com/rtomayko/posix-spawn/issues/90)
|
|
16
16
|
and
|
|
17
17
|
[terrapin#19](https://github.com/thoughtbot/terrapin/pull/19)
|
|
18
18
|
for more info.
|
|
19
|
-
*
|
|
19
|
+
* ability to load multiple clockfiles with one invocation
|
|
20
|
+
* job slugs based on job identifier, e.g. "Widget Co. Weekly Reports" -> "widget-co-weekly-reports"
|
|
21
|
+
* `--check-slug-uniqueness`
|
|
22
|
+
* `--environment-and-syntax-check`
|
|
23
|
+
* `--generate-dummy-crontab` to facilitate visualization with cronv
|
|
20
24
|
|
|
21
25
|
### Anti-Features
|
|
22
26
|
* ruby 3.0 is now the minimum version
|
|
23
27
|
|
|
24
28
|
### Code Improvements
|
|
25
29
|
* The code which implements the rails reloader/executor is now less complicated
|
|
26
|
-
* Code reorganization so there are no unnecessary methods in top-level Kernel namespace
|
|
30
|
+
* Code reorganization so there are no unnecessary methods in top-level `Kernel` namespace
|
|
27
31
|
* top-level DSL methods are now implemented with refinements, so they don't polute other code
|
|
28
32
|
|
|
29
33
|
|
|
30
34
|
### Migrating from ruby-clock version 1 to version 2
|
|
31
|
-
|
|
32
35
|
* The minimum ruby version is 3.0
|
|
33
36
|
* The top of every Clockfile must begin with `using RubyClock::DSL`
|
|
34
37
|
* If you have an existing `def schedule.around_trigger`, you will need to change it to use the new
|
|
@@ -37,6 +40,7 @@
|
|
|
37
40
|
`every`, `cron`, and `on_error` at the top-level, without referencing `schedule`.
|
|
38
41
|
* You now have the option of catching and reporting errors encountered when parsing the Clockfile.
|
|
39
42
|
* There is no longer a need to have a binstub in rails. You can delete bin/clock from your app.
|
|
43
|
+
* remove the `posix-spawn` gem from your project
|
|
40
44
|
* The invocations (in Procfile, or wherever else you start ruby-clock) should change from
|
|
41
45
|
|
|
42
46
|
bundle exec rails runner bin/clock
|
data/README.md
CHANGED
|
@@ -33,7 +33,7 @@ ruby >= 3.0 is required.
|
|
|
33
33
|
Add these lines to your application's Gemfile:
|
|
34
34
|
|
|
35
35
|
```ruby
|
|
36
|
-
gem 'ruby-clock'
|
|
36
|
+
gem 'ruby-clock', '2.0.0.beta10'
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
And then execute:
|
|
@@ -71,6 +71,11 @@ This will ignore Clockfile and only read jobs from clocks/MyClockfile:
|
|
|
71
71
|
|
|
72
72
|
bundle exec clock clocks/MyClockfile
|
|
73
73
|
|
|
74
|
+
You can also load multiple files with one invocation
|
|
75
|
+
(although a better approach might be to load your subfiles within a top-level Clockfile):
|
|
76
|
+
|
|
77
|
+
bundle exec clock clocks/daily.rb clocks/weekly.rb
|
|
78
|
+
|
|
74
79
|
### Rails
|
|
75
80
|
|
|
76
81
|
To run your clock process in your app's environment:
|
|
@@ -150,6 +155,28 @@ is valid during dev, or in automate tests.
|
|
|
150
155
|
assert(system("bundle exec --environment-and-syntax-check clock/my_clockfile.rb"))
|
|
151
156
|
```
|
|
152
157
|
|
|
158
|
+
You can use `--check-slug-uniqueness` to check if all the auto-generated slugs are unique. If you have
|
|
159
|
+
multiple files with jobs, you need to pass them all in with one invocation in order to check global uniqueness.
|
|
160
|
+
|
|
161
|
+
```ruby
|
|
162
|
+
# system returns true/false depending on 0/1 exit status of process
|
|
163
|
+
assert(system("bundle exec --check-slug-uniqueness")) # loads Clockfile
|
|
164
|
+
assert(system("bundle exec --check-slug-uniqueness clock/weekly.rb clock/daily.rb")) # load specific files
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
#### Visualization with cronv
|
|
168
|
+
|
|
169
|
+
Using the `--generate-dummy-crontab` flag you can visualize your schedule with [cronv](https://github.com/takumakanari/cronv).
|
|
170
|
+
For your jobs with cron-style schedules, it will generate a dummy crontab file that can be ingested by cronv.
|
|
171
|
+
For your jobs with "Every X seconds" schedules, a comment will be made in the file and they will not be vizualized.
|
|
172
|
+
|
|
173
|
+
```console
|
|
174
|
+
bundle exec clock --generate-dummy-crontab Clockfile ../clock/daily.rb ../clock/weekly.rb > dummycron.txt
|
|
175
|
+
## IMPORTANT: open dummycron.txt in an editor and remove the boot startup message cruft from the top
|
|
176
|
+
cat dummycron.txt | /Users/your-username/go/bin/cronv -d 1d -o ./my_cron_schedule.html
|
|
177
|
+
open dummycron
|
|
178
|
+
```
|
|
179
|
+
|
|
153
180
|
## More Config and Capabilities
|
|
154
181
|
|
|
155
182
|
### Error Handling
|
|
@@ -297,7 +324,7 @@ There are also `rake_execute` and `rake_async`.
|
|
|
297
324
|
See [the code](https://github.com/jjb/ruby-clock/blob/main/lib/ruby-clock/rake.rb)
|
|
298
325
|
and [this article](https://code.jjb.cc/running-rake-tasks-from-within-ruby-on-rails-code) for more info.
|
|
299
326
|
|
|
300
|
-
### Job Identifier
|
|
327
|
+
### Job Identifier & Slug
|
|
301
328
|
|
|
302
329
|
ruby-clock adds the `identifier` method to `Rufus::Scheduler::Job`. This method will return the job's
|
|
303
330
|
[name](https://github.com/jmettraux/rufus-scheduler/#name--string) if one was given.
|
|
@@ -305,30 +332,35 @@ If a name is not given, the last non-comment code line in the job's block
|
|
|
305
332
|
will be used instead. If for some reason an error is encountered while calculating this, the next
|
|
306
333
|
fallback is the line number of the job in Clockfile.
|
|
307
334
|
|
|
308
|
-
|
|
335
|
+
There is also the `slug` method, which produces a slug using
|
|
336
|
+
[ActiveSupport parameterize](https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize),
|
|
337
|
+
and with underscores changed to hyphens.
|
|
338
|
+
If the `activesupport` gem is not in your Gemfile and you attempt to use `slug`, it will fail.
|
|
339
|
+
|
|
340
|
+
Some examples of identifiers and slugs:
|
|
309
341
|
|
|
310
342
|
```ruby
|
|
311
343
|
every '1 second', name: 'my job' do
|
|
312
344
|
Foo.bar
|
|
313
345
|
end
|
|
314
|
-
#
|
|
346
|
+
# my job, my-job
|
|
315
347
|
|
|
316
348
|
every '1 day' do
|
|
317
349
|
daily_things = Foo.setup_daily
|
|
318
350
|
daily_things.process
|
|
319
351
|
# TODO: figure out best time of day
|
|
320
352
|
end
|
|
321
|
-
#
|
|
353
|
+
# daily_things.process, daily-things-process
|
|
322
354
|
|
|
323
355
|
# n.b. ruby-clock isn't yet smart enough to remove trailing comments
|
|
324
356
|
every '1 week' do
|
|
325
357
|
weekly_things = Foo.setup_weekly
|
|
326
358
|
weekly_things.process # does this work???!1~
|
|
327
359
|
end
|
|
328
|
-
#
|
|
360
|
+
# weekly_things.process # does this work???!1~, weekly-things-process-does-this-work-1
|
|
329
361
|
```
|
|
330
362
|
|
|
331
|
-
|
|
363
|
+
The identifier can be used for keeping track of job behavior in logs or a
|
|
332
364
|
stats tracker. For example:
|
|
333
365
|
|
|
334
366
|
```ruby
|
|
@@ -356,6 +388,18 @@ every '10 seconds', name: 'thread stats' do
|
|
|
356
388
|
end
|
|
357
389
|
```
|
|
358
390
|
|
|
391
|
+
The slug can be used for similar purposes where a slug-style string is needed. Here you can report
|
|
392
|
+
your job to a scheduled job monitor:
|
|
393
|
+
|
|
394
|
+
```ruby
|
|
395
|
+
# TODO proper example for healthcheks
|
|
396
|
+
around_action do |job_proc, job_info|
|
|
397
|
+
Net::HTTP.get("https://mymonitor.example.com/APIKEY/start/#{job_info.slug}")
|
|
398
|
+
job_proc.call
|
|
399
|
+
Net::HTTP.get("https://mymonitor.example.com/APIKEY/stop/#{job_info.slug}")
|
|
400
|
+
end
|
|
401
|
+
```
|
|
402
|
+
|
|
359
403
|
### Other rufus-scheduler Options
|
|
360
404
|
|
|
361
405
|
All [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler/) options are set to defaults.
|
data/example-app/Clockfile
CHANGED
data/example-app/Gemfile
CHANGED
data/exe/clock
CHANGED
|
@@ -9,27 +9,43 @@ RubyClock.instance.prepare_rake
|
|
|
9
9
|
RubyClock.instance.schedule.pause
|
|
10
10
|
RubyClock.instance.add_rails_executor_to_around_actions
|
|
11
11
|
|
|
12
|
-
clockfile = 'Clockfile'
|
|
13
12
|
check_syntax = false
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
case ARGV[
|
|
18
|
-
when
|
|
19
|
-
|
|
13
|
+
check_slug_uniqueness = false
|
|
14
|
+
generate_dummy_crontab = false
|
|
15
|
+
if '--' == ARGV[0][0..1]
|
|
16
|
+
case ARGV[0]
|
|
17
|
+
when '--environment-and-syntax-check'
|
|
18
|
+
check_syntax = true
|
|
19
|
+
when '--check-slug-uniqueness'
|
|
20
|
+
check_slug_uniqueness = true
|
|
21
|
+
when '--generate-dummy-crontab'
|
|
22
|
+
generate_dummy_crontab = true
|
|
23
|
+
else
|
|
24
|
+
raise 'unknown option'
|
|
25
|
+
end
|
|
26
|
+
if ARGV[1]
|
|
27
|
+
clockfiles = ARGV[1..]
|
|
28
|
+
else
|
|
29
|
+
clockfiles = ['Clockfile']
|
|
30
|
+
end
|
|
31
|
+
else
|
|
32
|
+
if ARGV[0]
|
|
33
|
+
clockfiles = ARGV[0..]
|
|
34
|
+
else
|
|
35
|
+
clockfiles = ['Clockfile']
|
|
20
36
|
end
|
|
21
|
-
when String
|
|
22
|
-
clockfile = ARGV[0]
|
|
23
37
|
end
|
|
24
38
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
RubyClock.instance.on_error
|
|
30
|
-
|
|
39
|
+
clockfiles.each do |clockfile|
|
|
40
|
+
begin
|
|
41
|
+
load clockfile
|
|
42
|
+
rescue => clockfile_error
|
|
43
|
+
if RubyClock.instance.on_error
|
|
44
|
+
RubyClock.instance.on_error.call("An error has occured while parsing the clockfile #{clockfile}", clockfile_error)
|
|
45
|
+
end
|
|
31
46
|
|
|
32
|
-
|
|
47
|
+
raise
|
|
48
|
+
end
|
|
33
49
|
end
|
|
34
50
|
|
|
35
51
|
RubyClock.instance.ensure_around_trigger_has_not_been_redefined
|
|
@@ -37,6 +53,33 @@ RubyClock.instance.freeze_around_actions
|
|
|
37
53
|
|
|
38
54
|
if check_syntax
|
|
39
55
|
puts "✨ Environment & Syntax OK ✨"
|
|
56
|
+
elsif check_slug_uniqueness
|
|
57
|
+
slugs = {}
|
|
58
|
+
RubyClock.instance.schedule.jobs.each do |j|
|
|
59
|
+
if slugs[j.slug]
|
|
60
|
+
slugs[j.slug] +=1
|
|
61
|
+
else
|
|
62
|
+
slugs[j.slug] = 1
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
slugs_with_duplicates = []
|
|
66
|
+
slugs.each{|s,count| slugs_with_duplicates << s if count > 1 }
|
|
67
|
+
if slugs_with_duplicates.any?
|
|
68
|
+
puts "The following slugs have duplicates: #{slugs_with_duplicates}"
|
|
69
|
+
exit(false)
|
|
70
|
+
else
|
|
71
|
+
puts "✨ All Slugs Are Unique ✨"
|
|
72
|
+
end
|
|
73
|
+
elsif generate_dummy_crontab
|
|
74
|
+
text = ''
|
|
75
|
+
RubyClock.instance.schedule.jobs.each do |j|
|
|
76
|
+
if j.respond_to?(:cron_line)
|
|
77
|
+
text << "#{j.cron_line.original} #{j.slug}\n"
|
|
78
|
+
else
|
|
79
|
+
text << "# every-#{j.frequency}-seconds #{j.slug}\n"
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
puts text
|
|
40
83
|
else
|
|
41
84
|
RubyClock.instance.run_jobs
|
|
42
85
|
end
|
data/lib/ruby-clock/version.rb
CHANGED
data/lib/rufus_monkeypatch.rb
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
require 'method_source'
|
|
2
|
+
|
|
2
3
|
class Rufus::Scheduler::Job
|
|
3
4
|
UNDESIRED_ELEMENTS = ['', '}', 'end']
|
|
5
|
+
|
|
4
6
|
def identifier
|
|
5
7
|
@identifier ||= begin
|
|
6
8
|
return name if name
|
|
@@ -18,4 +20,9 @@ class Rufus::Scheduler::Job
|
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
22
|
end
|
|
23
|
+
|
|
24
|
+
def slug
|
|
25
|
+
require 'active_support/inflector'
|
|
26
|
+
identifier.gsub('_', '-').parameterize
|
|
27
|
+
end
|
|
21
28
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby-clock
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.0.
|
|
4
|
+
version: 2.0.0.beta10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- John Bachir
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2023-
|
|
11
|
+
date: 2023-06-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rufus-scheduler
|