ruby-clock 2.0.0.beta1 → 2.0.0.beta3
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 +14 -1
- data/README.md +64 -21
- data/example-app/Clockfile +33 -4
- data/example-app/Gemfile.lock +9 -8
- data/example-rails-app/Clockfile +2 -16
- data/exe/clock +38 -11
- data/lib/ruby-clock/version.rb +2 -2
- data/lib/ruby-clock.rb +37 -2
- data/ruby-clock.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17d680fbe8df5efadea1cfa9123682fd2557828515fabfafad6825476669b368
|
4
|
+
data.tar.gz: d68673fdc64e3985a170d129b6642b00f323256904e4e54c07660bf1d73cd4e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 789d4ba0e97036cf12473ba5d0c6b190ce164e81573738c3f284910fb6de39fb13ae9a1e3342d6c621ede962b105923a05cc7c226c0294aea26dbb3d160c64f8
|
7
|
+
data.tar.gz: 381e0a04c4d0dc0425176d8414939658b669caaa0b1f2c2253c511506800ce01788eac2f4ef8cac9ebbdaac31031171917a8fac1965b4f3098f8f8c7a5b2cc8d
|
data/CHANGELOG.md
CHANGED
@@ -1,16 +1,29 @@
|
|
1
|
-
## 2.0.0
|
1
|
+
## 2.0.0 beta
|
2
2
|
|
3
3
|
* The way the [rails app reloader](https://guides.rubyonrails.org/threading_and_code_execution.html)
|
4
4
|
is implemented is now compatible with both rails 6 and 7
|
5
5
|
* The setup for rails is now less complicated
|
6
|
+
* RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS value is logged when starting
|
7
|
+
* Code reorganization so there are no unnecessary methods in top-level Kernel namespace
|
8
|
+
* DSL methods are now at the top-level namespace (`schedule.every` → `every`, `schedule.cron` → `cron`)
|
9
|
+
* error handler definition is now at the top-level namespace (`def schedule.on_error` → `on_error do`)
|
10
|
+
* around callbacks now have a top-level namespace method, which is different from the above in that...
|
11
|
+
* multiple around callbacks can be consecutively assigned
|
6
12
|
|
7
13
|
### Migrating from ruby-clock version 1 to version 2
|
8
14
|
|
15
|
+
* if you have and existing `def schedule.around_trigger`, you will need to change it to use the new
|
16
|
+
`around_action` method. see readme.
|
9
17
|
* There is no longer a need to have a binstub in rails. You can delete bin/clock from your app.
|
10
18
|
* The invocations (in Procfile, or wherever else you start ruby-clock) should change from
|
19
|
+
|
11
20
|
bundle exec rails runner bin/clock
|
12
21
|
to
|
22
|
+
|
13
23
|
bundle exec clock
|
24
|
+
* Your existing Clockfile will still work, but you now have the option to use
|
25
|
+
`every`, `cron`, and `on_error` at the top-level, without referencing `schedule`.
|
26
|
+
See the readme for examples.
|
14
27
|
|
15
28
|
## 1.0.0
|
16
29
|
|
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
THESE ARE THE DOCS FOR VERSION 2.0.0.beta
|
2
|
+
|
3
|
+
See version 1 docs here: https://github.com/jjb/ruby-clock/tree/v1.0.0
|
4
|
+
|
1
5
|
# ruby-clock
|
2
6
|
|
3
7
|
ruby-clock is a [job scheduler](https://en.wikipedia.org/wiki/Job_scheduler),
|
@@ -24,6 +28,8 @@ You can change this number with `RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS` in the enviro
|
|
24
28
|
|
25
29
|
## Installation
|
26
30
|
|
31
|
+
ruby >= 2.7 is required.
|
32
|
+
|
27
33
|
Add these lines to your application's Gemfile:
|
28
34
|
|
29
35
|
```ruby
|
@@ -41,17 +47,15 @@ Or install it yourself as:
|
|
41
47
|
## Usage
|
42
48
|
|
43
49
|
Create a file named Clockfile. This will hold your job definitions.
|
44
|
-
|
45
|
-
are the same as those of [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler/).
|
46
|
-
Read the rufus-scheduler documentation to see what you can do.
|
50
|
+
Define jobs like this:
|
47
51
|
|
48
52
|
```ruby
|
49
|
-
|
53
|
+
every('5 minutes') do
|
50
54
|
UserDataReports.generate
|
51
55
|
end
|
52
56
|
|
53
57
|
# do something every day, five minutes after midnight
|
54
|
-
|
58
|
+
cron '5 0 * * *' do
|
55
59
|
DailyActivitySummary.generate_and_send
|
56
60
|
end
|
57
61
|
```
|
@@ -99,7 +103,7 @@ Require your app's code at the top of Clockfile:
|
|
99
103
|
|
100
104
|
```ruby
|
101
105
|
require_relative './lib/app.rb'
|
102
|
-
|
106
|
+
every('5 minutes') do
|
103
107
|
...
|
104
108
|
```
|
105
109
|
|
@@ -141,14 +145,50 @@ You can catch and report errors raised in your jobs by defining an error catcher
|
|
141
145
|
the top of your Clockfile like this:
|
142
146
|
|
143
147
|
```ruby
|
144
|
-
|
148
|
+
on_error do |job, error|
|
145
149
|
ErrorReporter.track_exception(error)
|
146
150
|
end
|
147
151
|
```
|
148
152
|
|
149
153
|
### Callbacks
|
150
154
|
|
151
|
-
You can define
|
155
|
+
You can define around callbacks which will run for all jobs, like shown below.
|
156
|
+
This somewhat awkward syntax is necessary in order to enable the ability to define multiple callbacks.
|
157
|
+
(perhaps in different files, shared by multiple Clockfiles, etc.).
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
around_action do |job_proc, job_info|
|
161
|
+
puts "before1 #{job_info.class}"
|
162
|
+
job_proc.call
|
163
|
+
puts "after1"
|
164
|
+
end
|
165
|
+
|
166
|
+
around_action do |job_proc|
|
167
|
+
puts "before2"
|
168
|
+
job_proc.call
|
169
|
+
puts "after2"
|
170
|
+
end
|
171
|
+
|
172
|
+
every('2 seconds') do
|
173
|
+
puts "hello from a ruby-clock job"
|
174
|
+
end
|
175
|
+
```
|
176
|
+
|
177
|
+
|
178
|
+
```
|
179
|
+
before1 Rufus::Scheduler::EveryJob
|
180
|
+
before2
|
181
|
+
hello from a ruby-clock job
|
182
|
+
after2
|
183
|
+
after1
|
184
|
+
```
|
185
|
+
|
186
|
+
The around callbacks code will be run in the individual job thread.
|
187
|
+
|
188
|
+
rufus-scheduler also provides before and after hooks. ruby-clock does not provide convenience methods for these
|
189
|
+
but you can easily use them via the `schedule` object. These will run in the outer scheduling thread and not in
|
190
|
+
the job thread, so they may have slightly different behavior in some cases. There is likely no reason to use them
|
191
|
+
instead of `around_action`.
|
152
192
|
Read [the rufus-scheduler documentation](https://github.com/jmettraux/rufus-scheduler/#callbacks)
|
153
193
|
to learn how to do this. Where the documentation references `s`, you should use `schedule`.
|
154
194
|
|
@@ -157,7 +197,7 @@ to learn how to do this. Where the documentation references `s`, you should use
|
|
157
197
|
You can run shell commands in your jobs.
|
158
198
|
|
159
199
|
```ruby
|
160
|
-
|
200
|
+
every '1 day' do
|
161
201
|
shell('sh scripts/process_stuff.sh')
|
162
202
|
end
|
163
203
|
```
|
@@ -172,7 +212,7 @@ If you want to use other terrapin features, you can skip the `shell` command
|
|
172
212
|
and use terrapin directly:
|
173
213
|
|
174
214
|
```ruby
|
175
|
-
|
215
|
+
every '1 day' do
|
176
216
|
line = Terrapin::CommandLine.new('optimize_png', ":file")
|
177
217
|
Organization.with_new_logos.find_each do |o|
|
178
218
|
line.run(file: o.logo_file_path)
|
@@ -203,7 +243,7 @@ You can run tasks from within the persistent runtime of ruby-clock, without
|
|
203
243
|
needing to shell out and start another process.
|
204
244
|
|
205
245
|
```ruby
|
206
|
-
|
246
|
+
every '1 day' do
|
207
247
|
rake('reports:daily')
|
208
248
|
end
|
209
249
|
```
|
@@ -222,12 +262,12 @@ fallback is the line number of the job in Clockfile.
|
|
222
262
|
Some examples of jobs and their identifiers:
|
223
263
|
|
224
264
|
```ruby
|
225
|
-
|
265
|
+
every '1 second', name: 'my job' do
|
226
266
|
Foo.bar
|
227
267
|
end
|
228
268
|
# => my job
|
229
269
|
|
230
|
-
|
270
|
+
every '1 day' do
|
231
271
|
daily_things = Foo.setup_daily
|
232
272
|
daily_things.process
|
233
273
|
# TODO: figure out best time of day
|
@@ -235,7 +275,7 @@ end
|
|
235
275
|
# => daily_things.process
|
236
276
|
|
237
277
|
# n.b. ruby-clock isn't yet smart enough to remove trailing comments
|
238
|
-
|
278
|
+
every '1 week' do
|
239
279
|
weekly_things = Foo.setup_weekly
|
240
280
|
weekly_things.process # does this work???!1~
|
241
281
|
end
|
@@ -253,7 +293,7 @@ def schedule.on_post_trigger(job, trigger_time)
|
|
253
293
|
StatsTracker.increment('Clock: Job Executions')
|
254
294
|
end
|
255
295
|
|
256
|
-
|
296
|
+
every '10 seconds', name: 'thread stats' do
|
257
297
|
thread_usage = Hash.new(0)
|
258
298
|
schedule.work_threads(:active).each do |t|
|
259
299
|
thread_usage[t[:rufus_scheduler_job].identifier] += 1
|
@@ -268,14 +308,17 @@ schedule.every '10 seconds', name: 'thread stats' do
|
|
268
308
|
end
|
269
309
|
```
|
270
310
|
|
271
|
-
###
|
311
|
+
### Other rufus-scheduler Options
|
272
312
|
|
273
|
-
All rufus-scheduler options are set to defaults.
|
274
|
-
available in your Clockfile is
|
275
|
-
|
313
|
+
All [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler/) options are set to defaults.
|
314
|
+
There is a `schedule` variable available in your Clockfile, which is the singleton instance of `Rufus::Scheduler`.
|
315
|
+
ruby-clock methods such as `every` and `cron` are convenience methods which invoke `schedule.every`
|
316
|
+
and `schedule.cron`.
|
317
|
+
Anything you can do on this instance, you can do in your Clockfile.
|
318
|
+
See the rufus-scheduler documentation to see what you can do.
|
276
319
|
|
277
|
-
|
278
|
-
|
320
|
+
If you have ideas for rufus-scheduler features that can be brought in as
|
321
|
+
more abstract or default ruby-clock behavior, let me know!
|
279
322
|
|
280
323
|
## Syntax highlighting for Clockfile
|
281
324
|
|
data/example-app/Clockfile
CHANGED
@@ -1,11 +1,40 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
on_error do |job, error|
|
2
|
+
puts "An error has occurred with job #{job.identifier}: #{error.class}: #{error.message}"
|
3
3
|
end
|
4
|
+
# on_error do |job, error|
|
5
|
+
# raise error
|
6
|
+
# end
|
4
7
|
|
5
|
-
|
8
|
+
around_action do |job_proc, job_info|
|
9
|
+
puts "before1 #{job_info.class}"
|
10
|
+
job_proc.call
|
11
|
+
puts "after1"
|
12
|
+
end
|
13
|
+
|
14
|
+
around_action do |job_proc|
|
15
|
+
puts "before2"
|
16
|
+
job_proc.call
|
17
|
+
puts "after2"
|
18
|
+
end
|
19
|
+
|
20
|
+
around_action do |job_proc, job_info|
|
21
|
+
puts "before3 #{job_info.class}"
|
22
|
+
job_proc.call
|
23
|
+
puts "after3"
|
24
|
+
end
|
25
|
+
|
26
|
+
every('2 seconds') do
|
6
27
|
puts "hello from a ruby-clock job"
|
7
28
|
end
|
8
29
|
|
9
|
-
|
30
|
+
every('2 seconds') do
|
10
31
|
shell 'say hello'
|
11
32
|
end
|
33
|
+
|
34
|
+
every('2 seconds') do
|
35
|
+
raise "An error."
|
36
|
+
end
|
37
|
+
|
38
|
+
cron('*/10 * * * * *') do
|
39
|
+
puts "cron running on every 10th second #{Time.now}"
|
40
|
+
end
|
data/example-app/Gemfile.lock
CHANGED
@@ -1,31 +1,32 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
ruby-clock (0.
|
4
|
+
ruby-clock (2.0.0.beta2)
|
5
5
|
method_source
|
6
6
|
rufus-scheduler (~> 3.8)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
concurrent-ruby (1.1.
|
12
|
-
et-orbi (1.2.
|
11
|
+
concurrent-ruby (1.1.10)
|
12
|
+
et-orbi (1.2.7)
|
13
13
|
tzinfo
|
14
|
-
fugit (1.
|
15
|
-
et-orbi (~> 1
|
14
|
+
fugit (1.7.1)
|
15
|
+
et-orbi (~> 1, >= 1.2.7)
|
16
16
|
raabro (~> 1.4)
|
17
17
|
method_source (1.0.0)
|
18
18
|
raabro (1.4.0)
|
19
|
-
rufus-scheduler (3.8.
|
19
|
+
rufus-scheduler (3.8.2)
|
20
20
|
fugit (~> 1.1, >= 1.1.6)
|
21
|
-
tzinfo (2.0.
|
21
|
+
tzinfo (2.0.5)
|
22
22
|
concurrent-ruby (~> 1.0)
|
23
23
|
|
24
24
|
PLATFORMS
|
25
25
|
arm64-darwin-20
|
26
|
+
arm64-darwin-21
|
26
27
|
|
27
28
|
DEPENDENCIES
|
28
29
|
ruby-clock!
|
29
30
|
|
30
31
|
BUNDLED WITH
|
31
|
-
2.
|
32
|
+
2.3.8
|
data/example-rails-app/Clockfile
CHANGED
@@ -1,19 +1,5 @@
|
|
1
|
-
|
2
|
-
puts "An error has occurred: #{error.class}: #{error.message}"
|
3
|
-
end
|
4
|
-
|
5
|
-
schedule.every('2 seconds') do
|
6
|
-
puts "hello from a ruby-clock job"
|
7
|
-
end
|
1
|
+
load '../example-app/Clockfile'
|
8
2
|
|
9
|
-
|
10
|
-
shell 'say hello'
|
11
|
-
end
|
12
|
-
|
13
|
-
schedule.every('2 seconds') do
|
3
|
+
every('2 seconds') do
|
14
4
|
puts Example.count
|
15
5
|
end
|
16
|
-
|
17
|
-
schedule.every('2 seconds') do
|
18
|
-
raise "An error."
|
19
|
-
end
|
data/exe/clock
CHANGED
@@ -23,23 +23,50 @@ class Rufus::Scheduler::Job
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
RubyClock.instance.listen_to_signals
|
27
|
+
RubyClock.instance.prepare_rake
|
28
|
+
RubyClock.instance.schedule.pause
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
## Add methods to top-level namespace
|
33
|
+
def schedule
|
34
|
+
RubyClock.instance.schedule
|
35
|
+
end
|
36
|
+
|
37
|
+
def on_error(&on_error_block)
|
38
|
+
RubyClock.instance.on_error = on_error_block
|
39
|
+
def schedule.on_error(job, error)
|
40
|
+
RubyClock.instance.on_error.call(job, error)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def around_action(&b)
|
45
|
+
RubyClock.instance.around_actions << b
|
46
|
+
end
|
47
|
+
|
48
|
+
def cron(...)
|
49
|
+
RubyClock.instance.schedule.cron(...)
|
50
|
+
end
|
51
|
+
|
52
|
+
def every(...)
|
53
|
+
RubyClock.instance.schedule.every(...)
|
54
|
+
end
|
55
|
+
|
56
|
+
def shell(string)
|
57
|
+
RubyClock.instance.shell(string)
|
58
|
+
end
|
59
|
+
#####################################
|
27
60
|
|
28
|
-
listen_to_signals
|
29
|
-
prepare_rake
|
30
|
-
schedule.pause
|
31
61
|
|
32
62
|
load ARGV[0] || 'Clockfile'
|
33
63
|
|
34
64
|
if defined?(::Rails)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
::Rails.application.reloader.wrap do
|
39
|
-
@old_around_trigger.call(job){ yield }
|
40
|
-
end
|
65
|
+
around_action do |job_proc|
|
66
|
+
::Rails.application.reloader.wrap do
|
67
|
+
job_proc.call
|
41
68
|
end
|
42
69
|
end
|
43
70
|
end
|
44
71
|
|
45
|
-
run_jobs
|
72
|
+
RubyClock.instance.run_jobs
|
data/lib/ruby-clock/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION = "2.0.0.
|
1
|
+
class RubyClock
|
2
|
+
VERSION = "2.0.0.beta3"
|
3
3
|
end
|
data/lib/ruby-clock.rb
CHANGED
@@ -1,9 +1,30 @@
|
|
1
1
|
require "ruby-clock/version"
|
2
2
|
require 'rufus-scheduler'
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
class RubyClock
|
6
|
+
|
7
|
+
include Singleton
|
8
|
+
|
9
|
+
attr_accessor :on_error, :around_actions
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@around_actions = []
|
13
|
+
|
14
|
+
def schedule.around_trigger(job_info, &job_proc)
|
15
|
+
RubyClock.instance.call_with_around_action_stack(
|
16
|
+
RubyClock.instance.around_actions.reverse,
|
17
|
+
job_proc,
|
18
|
+
job_info
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def wait_seconds
|
24
|
+
ENV['RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS']&.to_i || 29
|
25
|
+
end
|
3
26
|
|
4
|
-
module RubyClock
|
5
27
|
def shutdown
|
6
|
-
wait_seconds = ENV['RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS']&.to_i || 29
|
7
28
|
puts "Shutting down ruby-clock. Waiting #{wait_seconds} seconds for jobs to finish..."
|
8
29
|
schedule.shutdown(wait: wait_seconds)
|
9
30
|
puts "...done 🐈️ 👋"
|
@@ -21,6 +42,7 @@ module RubyClock
|
|
21
42
|
end
|
22
43
|
end
|
23
44
|
end
|
45
|
+
puts "RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS is set to #{wait_seconds}"
|
24
46
|
end
|
25
47
|
|
26
48
|
def schedule
|
@@ -106,4 +128,17 @@ module RubyClock
|
|
106
128
|
end
|
107
129
|
end
|
108
130
|
|
131
|
+
def call_with_around_action_stack(wrappers, job_proc, job_info)
|
132
|
+
case wrappers.count
|
133
|
+
when 0
|
134
|
+
job_proc.call(job_info)
|
135
|
+
else
|
136
|
+
call_with_around_action_stack(
|
137
|
+
wrappers[1..],
|
138
|
+
Proc.new{ wrappers.first.call(job_proc, job_info) },
|
139
|
+
job_info
|
140
|
+
)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
109
144
|
end
|
data/ruby-clock.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
|
|
10
10
|
# spec.description = %q{TODO: Write a longer description or delete this line.}
|
11
11
|
spec.homepage = "https://github.com/jjb/ruby-clock"
|
12
12
|
spec.license = "MIT"
|
13
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
13
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
14
14
|
|
15
15
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
16
16
|
|
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.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Bachir
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-10-
|
11
|
+
date: 2022-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rufus-scheduler
|
@@ -159,7 +159,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
159
159
|
requirements:
|
160
160
|
- - ">="
|
161
161
|
- !ruby/object:Gem::Version
|
162
|
-
version: 2.
|
162
|
+
version: 2.7.0
|
163
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
164
|
requirements:
|
165
165
|
- - ">"
|