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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 567b66555b094f4c722a3340b9cc5ca99abab18918033ed972dc8c65ce242b18
4
- data.tar.gz: 2c9a42194dcd969623b04b1bfc21eb327cdd225322703a488f87fa1819a9302c
3
+ metadata.gz: 17d680fbe8df5efadea1cfa9123682fd2557828515fabfafad6825476669b368
4
+ data.tar.gz: d68673fdc64e3985a170d129b6642b00f323256904e4e54c07660bf1d73cd4e3
5
5
  SHA512:
6
- metadata.gz: 0cdd8a85ec8f8de256486f027639c9d4c341131eb7dc88d519baf249733c7c655f72af923b8c8914b51d405f09a24cd9aa17efc4fc96cf807dcacdd74b024878
7
- data.tar.gz: e655dce4688f88154bac50957fb321f11e07dc7d40ee5fc679a25d0e0a8feff097016ac7df128e77f4eaccae5e3fa817caa76d5a300bee364e48999bd4c0ea50
6
+ metadata.gz: 789d4ba0e97036cf12473ba5d0c6b190ce164e81573738c3f284910fb6de39fb13ae9a1e3342d6c621ede962b105923a05cc7c226c0294aea26dbb3d160c64f8
7
+ data.tar.gz: 381e0a04c4d0dc0425176d8414939658b669caaa0b1f2c2253c511506800ce01788eac2f4ef8cac9ebbdaac31031171917a8fac1965b4f3098f8f8c7a5b2cc8d
data/CHANGELOG.md CHANGED
@@ -1,16 +1,29 @@
1
- ## 2.0.0.beta1
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
- The DSL and capabilities
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
- schedule.every('5 minutes') do
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
- schedule.cron '5 0 * * *' do
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
- schedule.every('5 minutes') do
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
- def schedule.on_error(job, error)
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 before, after, and around callbacks which will run for all jobs.
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
- schedule.every '1 day' do
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
- schedule.every '1 day' do
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
- schedule.every '1 day' do
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
- schedule.every '1 second', name: 'my job' do
265
+ every '1 second', name: 'my job' do
226
266
  Foo.bar
227
267
  end
228
268
  # => my job
229
269
 
230
- schedule.every '1 day' do
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
- schedule.every '1 week' do
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
- schedule.every '10 seconds', name: 'thread stats' do
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
- ### other rufus-scheduler Options
311
+ ### Other rufus-scheduler Options
272
312
 
273
- All rufus-scheduler options are set to defaults. The `schedule` variable
274
- available in your Clockfile is an instance of `Rufus::Scheduler`,
275
- so anything you can do on this instance, you can do in your Clockfile.
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
- Perhaps in the future ruby-clock will add some easier specific configuration
278
- capabilities for some things. Let me know if you have a request!
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
 
@@ -1,11 +1,40 @@
1
- def schedule.on_error(job, error)
2
- raise error
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
- schedule.every('2 seconds') do
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
- schedule.every('2 seconds') do
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
@@ -1,31 +1,32 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- ruby-clock (0.8.0.rc3)
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.9)
12
- et-orbi (1.2.5)
11
+ concurrent-ruby (1.1.10)
12
+ et-orbi (1.2.7)
13
13
  tzinfo
14
- fugit (1.5.2)
15
- et-orbi (~> 1.1, >= 1.1.8)
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.0)
19
+ rufus-scheduler (3.8.2)
20
20
  fugit (~> 1.1, >= 1.1.6)
21
- tzinfo (2.0.4)
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.2.28
32
+ 2.3.8
@@ -1,19 +1,5 @@
1
- def schedule.on_error(job, error)
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
- schedule.every('2 seconds') do
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
- include RubyClock
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
- schedule.instance_eval do
36
- @old_around_trigger = method :around_trigger
37
- def around_trigger(job)
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
@@ -1,3 +1,3 @@
1
- module RubyClock
2
- VERSION = "2.0.0.beta1"
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.3.0")
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.beta1
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-01 00:00:00.000000000 Z
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.3.0
162
+ version: 2.7.0
163
163
  required_rubygems_version: !ruby/object:Gem::Requirement
164
164
  requirements:
165
165
  - - ">"