ruby-clock 2.0.0.beta1 → 2.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
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
  - - ">"