ruby-clock 2.0.0.beta7 → 2.0.0.beta9

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: 0a64343fae81372c459f3ea52c8358f2b9425c16fdb354ba29eeff18cc836927
4
- data.tar.gz: cd17b15fcc7dcbdccc6e83dedab43316036a1b2a3a3cc143add9d7523586f4d2
3
+ metadata.gz: cc7625ea594c3028d9503ad7c1013b7888c776a51bf5853ada639cef1b9d754c
4
+ data.tar.gz: 6c3d8841a45cd336a108c334b94e35441200885b2329ac6dbf39751dd32b8451
5
5
  SHA512:
6
- metadata.gz: 9e07fe25a8ee147c0dfca4fb90904b5a2c4a79d4c0e59953a616466080a626d95a457a8efd1844e92bed7a130fd0ad15480beb4be9155ab3d7a3f903decf5024
7
- data.tar.gz: d8d40783de5f21398e1170f6bbfd9212fae1ba90a879aaec68002d433a9499455f6e506c968e8e040cce81f99e74991bba8c35a29e6ff94dd34b3dcd763f3c5d
6
+ metadata.gz: f8067434425e00d84371aa7242d78ebf9a24f355e2f13ec1cba79e7140301d2902b4bf2902237023b277ebfd876c88761b4cdc15de33df8225837ab074bb1781
7
+ data.tar.gz: 93eb07e47f6a8ec2cad4f7916090bb2f310657cca5bae3adef090e7a08f2de7d9b4af62f9e6649e1ab35eb5b2fc81d4a2063971bea6b37e3759473cd722ea47a
data/CHANGELOG.md CHANGED
@@ -5,29 +5,32 @@
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
+ * 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`
19
23
 
20
24
  ### Anti-Features
21
25
  * ruby 3.0 is now the minimum version
22
26
 
23
27
  ### Code Improvements
24
28
  * The code which implements the rails reloader/executor is now less complicated
25
- * Code reorganization so there are no unnecessary methods in top-level Kernel namespace
29
+ * Code reorganization so there are no unnecessary methods in top-level `Kernel` namespace
26
30
  * top-level DSL methods are now implemented with refinements, so they don't polute other code
27
31
 
28
32
 
29
33
  ### Migrating from ruby-clock version 1 to version 2
30
-
31
34
  * The minimum ruby version is 3.0
32
35
  * The top of every Clockfile must begin with `using RubyClock::DSL`
33
36
  * If you have an existing `def schedule.around_trigger`, you will need to change it to use the new
@@ -36,6 +39,7 @@
36
39
  `every`, `cron`, and `on_error` at the top-level, without referencing `schedule`.
37
40
  * You now have the option of catching and reporting errors encountered when parsing the Clockfile.
38
41
  * There is no longer a need to have a binstub in rails. You can delete bin/clock from your app.
42
+ * remove the `posix-spawn` gem from your project
39
43
  * The invocations (in Procfile, or wherever else you start ruby-clock) should change from
40
44
 
41
45
  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.beta9'
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:
@@ -139,6 +144,27 @@ to another process or file. To change this behavior and have logs flush immediat
139
144
  add `$stdout.sync = true` to the top of your Clockfile.
140
145
 
141
146
 
147
+ #### Testing
148
+
149
+ You can use the `--environment-and-syntax-check` flag to load the app environment and check
150
+ Clockfile syntax without actually running jobs. This can be used to check if cron syntax
151
+ is valid during dev, or in automate tests.
152
+
153
+ ```ruby
154
+ # system returns true/false depending on 0/1 exit status of process
155
+ assert(system("bundle exec --environment-and-syntax-check clock/my_clockfile.rb"))
156
+ ```
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
+
142
168
  ## More Config and Capabilities
143
169
 
144
170
  ### Error Handling
@@ -151,7 +177,7 @@ error reports about problems while loading the Clockfile:
151
177
  on_error do |job, error|
152
178
  case job
153
179
  when String # this means there was a problem parsing the Clockfile while starting
154
- ErrorReporter.track_exception(error, tag: 'clock', severity: 'high')
180
+ ErrorReporter.track_exception(StandardError.new(error), tag: 'clock', severity: 'high')
155
181
  else
156
182
  ErrorReporter.track_exception(error, tag: 'clock', custom_attribute: {job_name: job.identifier})
157
183
  end
@@ -286,7 +312,7 @@ There are also `rake_execute` and `rake_async`.
286
312
  See [the code](https://github.com/jjb/ruby-clock/blob/main/lib/ruby-clock/rake.rb)
287
313
  and [this article](https://code.jjb.cc/running-rake-tasks-from-within-ruby-on-rails-code) for more info.
288
314
 
289
- ### Job Identifier
315
+ ### Job Identifier & Slug
290
316
 
291
317
  ruby-clock adds the `identifier` method to `Rufus::Scheduler::Job`. This method will return the job's
292
318
  [name](https://github.com/jmettraux/rufus-scheduler/#name--string) if one was given.
@@ -294,30 +320,35 @@ If a name is not given, the last non-comment code line in the job's block
294
320
  will be used instead. If for some reason an error is encountered while calculating this, the next
295
321
  fallback is the line number of the job in Clockfile.
296
322
 
297
- Some examples of jobs and their identifiers:
323
+ There is also the `slug` method, which produces a slug using
324
+ [ActiveSupport parameterize](https://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize),
325
+ and with underscores changed to hyphens.
326
+ If the `activesupport` gem is not in your Gemfile and you attempt to use `slug`, it will fail.
327
+
328
+ Some examples of identifiers and slugs:
298
329
 
299
330
  ```ruby
300
331
  every '1 second', name: 'my job' do
301
332
  Foo.bar
302
333
  end
303
- # => my job
334
+ # my job, my-job
304
335
 
305
336
  every '1 day' do
306
337
  daily_things = Foo.setup_daily
307
338
  daily_things.process
308
339
  # TODO: figure out best time of day
309
340
  end
310
- # => daily_things.process
341
+ # daily_things.process, daily-things-process
311
342
 
312
343
  # n.b. ruby-clock isn't yet smart enough to remove trailing comments
313
344
  every '1 week' do
314
345
  weekly_things = Foo.setup_weekly
315
346
  weekly_things.process # does this work???!1~
316
347
  end
317
- # => weekly_things.process # does this work???!1~
348
+ # weekly_things.process # does this work???!1~, weekly-things-process-does-this-work-1
318
349
  ```
319
350
 
320
- This can be used for keeping track of job behavior in logs or a
351
+ The identifier can be used for keeping track of job behavior in logs or a
321
352
  stats tracker. For example:
322
353
 
323
354
  ```ruby
@@ -345,6 +376,18 @@ every '10 seconds', name: 'thread stats' do
345
376
  end
346
377
  ```
347
378
 
379
+ The slug can be used for similar purposes where a slug-style string is needed. Here you can report
380
+ your job to a scheduled job monitor:
381
+
382
+ ```ruby
383
+ # TODO proper example for healthcheks
384
+ around_action do |job_proc, job_info|
385
+ Net::HTTP.get("https://mymonitor.example.com/APIKEY/start/#{job_info.slug}")
386
+ job_proc.call
387
+ Net::HTTP.get("https://mymonitor.example.com/APIKEY/stop/#{job_info.slug}")
388
+ end
389
+ ```
390
+
348
391
  ### Other rufus-scheduler Options
349
392
 
350
393
  All [rufus-scheduler](https://github.com/jmettraux/rufus-scheduler/) options are set to defaults.
@@ -14,7 +14,7 @@ end
14
14
  # end
15
15
 
16
16
  around_action do |job_proc, job_info|
17
- puts "before1 #{job_info.class} #{job_info.identifier}"
17
+ puts "before1 #{job_info.class} #{job_info.identifier} #{job_info.slug}"
18
18
  job_proc.call
19
19
  puts "after1"
20
20
  end
data/example-app/Gemfile CHANGED
@@ -5,4 +5,5 @@ source "https://rubygems.org"
5
5
  ruby '>= 3.0'
6
6
 
7
7
  gem 'ruby-clock', path: '../'
8
+ gem 'activesupport'
8
9
  # gem 'terrapin'
data/exe/clock CHANGED
@@ -9,16 +9,64 @@ RubyClock.instance.prepare_rake
9
9
  RubyClock.instance.schedule.pause
10
10
  RubyClock.instance.add_rails_executor_to_around_actions
11
11
 
12
- begin
13
- load ARGV[0] || 'Clockfile'
14
- rescue => clockfile_error
15
- if RubyClock.instance.on_error
16
- RubyClock.instance.on_error.call("An error has occured while parsing the clockfile", clockfile_error)
12
+ check_syntax = false
13
+ check_slug_uniqueness = false
14
+ if '--' == ARGV[0][0..1]
15
+ case ARGV[0]
16
+ when '--environment-and-syntax-check'
17
+ check_syntax = true
18
+ when '--check-slug-uniqueness'
19
+ check_slug_uniqueness = true
20
+ else
21
+ raise 'unknown option'
17
22
  end
23
+ if ARGV[1]
24
+ clockfiles = ARGV[1..]
25
+ else
26
+ clockfiles = ['Clockfile']
27
+ end
28
+ else
29
+ if ARGV[0]
30
+ clockfiles = ARGV[0..]
31
+ else
32
+ clockfiles = ['Clockfile']
33
+ end
34
+ end
18
35
 
19
- raise
36
+ clockfiles.each do |clockfile|
37
+ begin
38
+ load clockfile
39
+ rescue => clockfile_error
40
+ if RubyClock.instance.on_error
41
+ RubyClock.instance.on_error.call("An error has occured while parsing the clockfile #{clockfile}", clockfile_error)
42
+ end
43
+
44
+ raise
45
+ end
20
46
  end
21
47
 
22
48
  RubyClock.instance.ensure_around_trigger_has_not_been_redefined
23
49
  RubyClock.instance.freeze_around_actions
24
- RubyClock.instance.run_jobs
50
+
51
+ if check_syntax
52
+ puts "✨ Environment & Syntax OK ✨"
53
+ elsif check_slug_uniqueness
54
+ slugs = {}
55
+ RubyClock.instance.schedule.jobs.each do |j|
56
+ if slugs[j.slug]
57
+ slugs[j.slug] +=1
58
+ else
59
+ slugs[j.slug] = 1
60
+ end
61
+ end
62
+ slugs_with_duplicates = []
63
+ slugs.each{|s,count| slugs_with_duplicates << s if count > 1 }
64
+ if slugs_with_duplicates.any?
65
+ puts "The following slugs have duplicates: #{slugs_with_duplicates}"
66
+ exit(false)
67
+ else
68
+ puts "✨ All Slugs Are Unique ✨"
69
+ end
70
+ else
71
+ RubyClock.instance.run_jobs
72
+ end
@@ -1,3 +1,3 @@
1
1
  class RubyClock
2
- VERSION = "2.0.0.beta7"
2
+ VERSION = "2.0.0.beta9"
3
3
  end
@@ -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.beta7
4
+ version: 2.0.0.beta9
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-04-06 00:00:00.000000000 Z
11
+ date: 2023-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rufus-scheduler