ruby-clock 2.0.0.beta2 → 2.0.0.beta4

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: 9fdfa3656f0ffbdf60b162a594809e29e9f0579cf3f5f52e98ffd857a811c348
4
- data.tar.gz: f63dd579f2cd258f89f17666338ec9d433a63e2b93d0a400975ee6c1e61886fa
3
+ metadata.gz: 8900519602f68a1eb7e0a5b49aa1752c5a42ffb65a16b409b8f12c003237c568
4
+ data.tar.gz: bb9d30d35bafa38b970f061faa0416bffb66197f5fddd5d46a691c05e04fe82b
5
5
  SHA512:
6
- metadata.gz: 938ec658ba3837be8a90c49fdd8d2d6a050b1b6a19486bc2b10479e81370ed3fe5c0e4501293b02a2c8efcfe82d67974e887c2069270986f3398b89762c04707
7
- data.tar.gz: c3376b79456a66c2b3c1eb5492b9a0429e69ece7b5207a73d2792c8830c33355c14dc622c2a37e8b6b8e2b9b27cdaaa4d0c83449e6e9c8aca3ae2538e2a90af0
6
+ metadata.gz: 50482fd2178c9098bd8e2eb1218f56c56596d5983d82571246d5516cd977227a344598f056019027f2b97222ffc8a628eed503ed2d10defea116bfe5d6b953f1
7
+ data.tar.gz: 5eb78d5f6dffb1d09d09e9d1ada59a0bae9646253f789affec38311237b74b937192b1f7a414b2a5ff3e8fc2b34a3beb6fe1e8fda8a6aeffedfac80941e8a5a5
data/CHANGELOG.md CHANGED
@@ -1,15 +1,34 @@
1
1
  ## 2.0.0 beta
2
2
 
3
+ ### Features
3
4
  * The way the [rails app reloader](https://guides.rubyonrails.org/threading_and_code_execution.html)
4
5
  is implemented is now compatible with both rails 6 and 7
5
- * The setup for rails is now less complicated
6
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
7
  * 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`)
8
+ * Error handler definition is now at the top-level namespace (`def schedule.on_error` → `on_error do`)
9
+ * Around callbacks now have a top-level namespace method. `def schedule.around_trigger` → `around_action` - see readme
10
+ * Multiple around callbacks can be consecutively assigned - no need to put all behavior into one action
11
+ * Errors encountered when loading Clockfile (such as incorrect cron syntaxt)
12
+ will be reported to the error handler
13
+
14
+ ### Anti-Features
15
+ * rake and shell runners are no longer top-level (`shell` → `RubyClock::Runners.shell`, `rake` → `RubyClock::Runners.rake`)
16
+
17
+ ### Code Improvements
18
+ * The code which implements the rails reloader/executor is now less complicated
19
+ * Code reorganization so there are no unnecessary methods in top-level Kernel namespace
20
+
10
21
 
11
22
  ### Migrating from ruby-clock version 1 to version 2
12
23
 
24
+ * The top of every Clockfile must begin with `using RubyClock::DSL`
25
+ * rake and shell runners must be invoked like so: `RubyClock::Runners.rake`, `RubyClock::Runners.shell`, etc.
26
+ * If you have an existing `def schedule.around_trigger`, you will need to change it to use the new
27
+ `around_action` method. Failure to change this will silently appear to keep working,
28
+ but will break the rails reloader/executor implementation.
29
+ * Your existing Clockfile will still work, but you now have the option to use
30
+ `every`, `cron`, and `on_error` at the top-level, without referencing `schedule`.
31
+ See the readme for examples.
13
32
  * There is no longer a need to have a binstub in rails. You can delete bin/clock from your app.
14
33
  * The invocations (in Procfile, or wherever else you start ruby-clock) should change from
15
34
 
@@ -17,9 +36,6 @@
17
36
  to
18
37
 
19
38
  bundle exec clock
20
- * Your existing Clockfile will still work, but you now have the option to use
21
- `every`, `cron`, and `on_error` at the top-level, without referencing `schedule`.
22
- See the readme for examples.
23
39
 
24
40
  ## 1.0.0
25
41
 
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- THESE ARE THE DOCS FOR VERSION 2.0.0.beta2
1
+ THESE ARE THE DOCS FOR VERSION 2.0.0.beta
2
2
 
3
3
  See version 1 docs here: https://github.com/jjb/ruby-clock/tree/v1.0.0
4
4
 
@@ -50,6 +50,8 @@ Create a file named Clockfile. This will hold your job definitions.
50
50
  Define jobs like this:
51
51
 
52
52
  ```ruby
53
+ using RubyClock::DSL
54
+
53
55
  every('5 minutes') do
54
56
  UserDataReports.generate
55
57
  end
@@ -90,9 +92,9 @@ You may wish to
90
92
  for your jobs. You can do so with the around trigger:
91
93
 
92
94
  ```ruby
93
- def schedule.around_trigger(job)
95
+ around_action(job_proc)
94
96
  ActiveRecord::Base.uncached do
95
- yield
97
+ job_proc.call
96
98
  end
97
99
  end
98
100
  ```
@@ -142,17 +144,59 @@ add `$stdout.sync = true` to the top of your Clockfile.
142
144
  ### Error Handling
143
145
 
144
146
  You can catch and report errors raised in your jobs by defining an error catcher at
145
- the top of your Clockfile like this:
147
+ the top of your Clockfile like this. You should handle these two cases so that you can get
148
+ error reports about problems while loading the Clockfile:
146
149
 
147
150
  ```ruby
148
151
  on_error do |job, error|
149
- ErrorReporter.track_exception(error)
152
+ case job
153
+ when String # this means there was a problem parsing the Clockfile while starting
154
+ ErrorReporter.track_exception(error, tag: 'clock', severity: 'high')
155
+ else
156
+ ErrorReporter.track_exception(error, tag: 'clock', custom_attribute: {job_name: job.identifier})
157
+ end
150
158
  end
151
159
  ```
152
160
 
153
161
  ### Callbacks
154
162
 
155
- You can define before, after, and around callbacks which will run for all jobs.
163
+ You can define around callbacks which will run for all jobs, like shown below.
164
+ This somewhat awkward syntax is necessary in order to enable the ability to define multiple callbacks.
165
+ (perhaps in different files, shared by multiple Clockfiles, etc.).
166
+
167
+ ```ruby
168
+ around_action do |job_proc, job_info|
169
+ puts "before1 #{job_info.class}"
170
+ job_proc.call
171
+ puts "after1"
172
+ end
173
+
174
+ around_action do |job_proc|
175
+ puts "before2"
176
+ job_proc.call
177
+ puts "after2"
178
+ end
179
+
180
+ every('2 seconds') do
181
+ puts "hello from a ruby-clock job"
182
+ end
183
+ ```
184
+
185
+
186
+ ```
187
+ before1 Rufus::Scheduler::EveryJob
188
+ before2
189
+ hello from a ruby-clock job
190
+ after2
191
+ after1
192
+ ```
193
+
194
+ The around callbacks code will be run in the individual job thread.
195
+
196
+ rufus-scheduler also provides before and after hooks. ruby-clock does not provide convenience methods for these
197
+ but you can easily use them via the `schedule` object. These will run in the outer scheduling thread and not in
198
+ the job thread, so they may have slightly different behavior in some cases. There is likely no reason to use them
199
+ instead of `around_action`.
156
200
  Read [the rufus-scheduler documentation](https://github.com/jmettraux/rufus-scheduler/#callbacks)
157
201
  to learn how to do this. Where the documentation references `s`, you should use `schedule`.
158
202
 
@@ -162,7 +206,7 @@ You can run shell commands in your jobs.
162
206
 
163
207
  ```ruby
164
208
  every '1 day' do
165
- shell('sh scripts/process_stuff.sh')
209
+ RubyClock::Runners.shell('sh scripts/process_stuff.sh')
166
210
  end
167
211
  ```
168
212
 
@@ -208,11 +252,12 @@ needing to shell out and start another process.
208
252
 
209
253
  ```ruby
210
254
  every '1 day' do
211
- rake('reports:daily')
255
+ RubyClock::Runners.rake('reports:daily')
212
256
  end
213
257
  ```
214
258
 
215
- There is also `rake_execute` and `rake_async`. See [the code](https://github.com/jjb/ruby-clock/blob/main/lib/ruby-clock.rb)
259
+ There is also `RubyClock::Runners.rake_execute` and `RubyClock::Runners.rake_async`.
260
+ See [the code](https://github.com/jjb/ruby-clock/blob/main/lib/rake.rb)
216
261
  and [this article](https://code.jjb.cc/running-rake-tasks-from-within-ruby-on-rails-code) for more info.
217
262
 
218
263
  ### Job Identifier
@@ -250,10 +295,12 @@ This can be used for keeping track of job behavior in logs or a
250
295
  stats tracker. For example:
251
296
 
252
297
  ```ruby
253
- def schedule.on_post_trigger(job, trigger_time)
298
+ around_action(job_proc, job_info)
299
+ trigger_time = Time.now
300
+ job_proc.call
254
301
  duration = Time.now-trigger_time.to_t
255
302
  StatsTracker.value('Clock: Job Execution Time', duration.round(2))
256
- StatsTracker.value("Clock: Job #{job.identifier} Execution Time", duration.round(2))
303
+ StatsTracker.value("Clock: Job #{job_info.identifier} Execution Time", duration.round(2))
257
304
  StatsTracker.increment('Clock: Job Executions')
258
305
  end
259
306
 
@@ -1,5 +1,28 @@
1
+ using RubyClock::DSL
2
+
1
3
  on_error do |job, error|
2
- raise error
4
+ case job
5
+ when String
6
+ puts "#{job}: #{error.class}: #{error.message}"
7
+ else
8
+ puts "An error has occurred with job #{job.identifier}: #{error.class}: #{error.message}"
9
+ end
10
+ end
11
+
12
+ # on_error do |job, error|
13
+ # raise error
14
+ # end
15
+
16
+ around_action do |job_proc, job_info|
17
+ puts "before1 #{job_info.class}"
18
+ job_proc.call
19
+ puts "after1"
20
+ end
21
+
22
+ around_action do |job_proc|
23
+ puts "before2"
24
+ job_proc.call
25
+ puts "after2"
3
26
  end
4
27
 
5
28
  every('2 seconds') do
@@ -7,9 +30,25 @@ every('2 seconds') do
7
30
  end
8
31
 
9
32
  every('2 seconds') do
10
- shell 'say hello'
33
+ RubyClock::Runners.shell 'say hello'
34
+ end
35
+
36
+ every('2 seconds') do
37
+ raise "🐈️ this error is expected, to test the error catcher"
11
38
  end
12
39
 
13
40
  cron('*/10 * * * * *') do
14
41
  puts "cron running on every 10th second #{Time.now}"
15
42
  end
43
+
44
+ every('2 seconds') do
45
+ if defined?(schedule)
46
+ raise "💥 we do not expect the ruby-clock DSL to be available inside a job, but it is"
47
+ end
48
+ end
49
+
50
+ every('2 seconds') do
51
+ if defined?(shell) || defined?(rake)
52
+ puts "💥 we do not expect runners to be available inside a job, but it is"
53
+ end
54
+ 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.beta4)
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,23 +1,19 @@
1
- on_error do |job, error|
2
- puts "An error has occurred: #{error.class}: #{error.message}"
3
- end
1
+ using RubyClock::DSL
4
2
 
5
- every('2 seconds') do
6
- puts "hello from a ruby-clock job"
7
- end
3
+ load '../example-app/Clockfile'
8
4
 
9
5
  every('2 seconds') do
10
- shell 'say hello'
6
+ puts Example.count
11
7
  end
12
8
 
13
9
  every('2 seconds') do
14
- puts Example.count
10
+ puts Example.check_for_global_method
15
11
  end
16
12
 
17
13
  every('2 seconds') do
18
- raise "An error."
14
+ puts Example.check_for_runner
19
15
  end
20
16
 
21
- cron('*/10 * * * * *') do
22
- puts "cron running on every 10th second #{Time.now}"
17
+ every('2 seconds') do
18
+ RubyClock::Runners.rake 'about'
23
19
  end
@@ -1,2 +1,18 @@
1
1
  class Example < ApplicationRecord
2
+ def self.check_for_global_method
3
+ if defined?(schedule)
4
+ raise "💥 Oh no, the ruby-clock DSL is in the global environment! 💥"
5
+ else
6
+ "🦝"
7
+ end
8
+ end
9
+
10
+ def self.check_for_runner
11
+ if defined?(shell) || defined?(rake)
12
+ raise "💥 Oh no, the runners got included in the global environment! 💥"
13
+ else
14
+ "🐅"
15
+ end
16
+ end
17
+
2
18
  end
data/exe/clock CHANGED
@@ -1,71 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- begin
4
- require './config/environment.rb'
5
- puts "Detected rails app has been loaded."
6
- rescue LoadError
7
- end
8
-
9
3
  require 'ruby-clock'
10
- require 'method_source'
11
-
12
- class Rufus::Scheduler::Job
13
- def identifier
14
- @identifier ||= begin
15
- name || handler.source.split("\n").reject(&:empty?).grep_v(/#.*/)[-2].strip
16
- rescue
17
- begin
18
- source_location.join('-')
19
- rescue
20
- 'error-calculating-job-identifier'
21
- end
22
- end
23
- end
24
- end
25
-
4
+ RubyClock.detect_and_load_rails_app
5
+ require 'rufus_monkeypatch'
26
6
  RubyClock.instance.listen_to_signals
27
7
  RubyClock.instance.prepare_rake
28
8
  RubyClock.instance.schedule.pause
9
+ RubyClock.instance.add_rails_executor_to_around_actions
29
10
 
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)
11
+ begin
12
+ load ARGV[0] || 'Clockfile'
13
+ rescue => clockfile_error
14
+ if RubyClock.instance.on_error
15
+ RubyClock.instance.on_error.call("An error has occured while parsing the clockfile", clockfile_error)
41
16
  end
42
- end
43
-
44
- def cron(...)
45
- RubyClock.instance.schedule.cron(...)
46
- end
47
-
48
- def every(...)
49
- RubyClock.instance.schedule.every(...)
50
- end
51
17
 
52
- def shell(string)
53
- RubyClock.instance.shell(string)
54
- end
55
- #####################################
56
-
57
-
58
- load ARGV[0] || 'Clockfile'
59
-
60
- if defined?(::Rails)
61
- schedule.instance_eval do
62
- @old_around_trigger = method :around_trigger
63
- def around_trigger(job)
64
- ::Rails.application.reloader.wrap do
65
- @old_around_trigger.call(job){ yield }
66
- end
67
- end
68
- end
18
+ raise
69
19
  end
70
20
 
21
+ RubyClock.instance.freeze_around_actions
71
22
  RubyClock.instance.run_jobs
@@ -0,0 +1,33 @@
1
+ module RubyClock::AroundActions
2
+
3
+ attr_accessor :around_actions
4
+
5
+ def freeze_around_actions
6
+ @around_actions.freeze
7
+ end
8
+
9
+ def set_up_around_actions
10
+ @around_actions = []
11
+ def schedule.around_trigger(job_info, &job_proc)
12
+ RubyClock.instance.call_with_around_action_stack(
13
+ RubyClock.instance.around_actions.reverse,
14
+ job_proc,
15
+ job_info
16
+ )
17
+ end
18
+ end
19
+
20
+ def call_with_around_action_stack(wrappers, job_proc, job_info)
21
+ case wrappers.count
22
+ when 0
23
+ job_proc.call(job_info)
24
+ else
25
+ call_with_around_action_stack(
26
+ wrappers[1..],
27
+ Proc.new{ wrappers.first.call(job_proc, job_info) },
28
+ job_info
29
+ )
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,26 @@
1
+ module RubyClock::DSL
2
+ refine ::Kernel do
3
+ def schedule
4
+ RubyClock.instance.schedule
5
+ end
6
+
7
+ def on_error(&on_error_block)
8
+ RubyClock.instance.on_error = on_error_block
9
+ def schedule.on_error(job, error)
10
+ RubyClock.instance.on_error.call(job, error)
11
+ end
12
+ end
13
+
14
+ def around_action(&b)
15
+ RubyClock.instance.around_actions << b
16
+ end
17
+
18
+ def cron(...)
19
+ RubyClock.instance.schedule.cron(...)
20
+ end
21
+
22
+ def every(...)
23
+ RubyClock.instance.schedule.every(...)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,24 @@
1
+ # There is also rails-relevant code in rake.rb
2
+ module RubyClock::Rails
3
+ module ClassMethods
4
+ def detect_and_load_rails_app
5
+ begin
6
+ require './config/environment.rb'
7
+ puts "Detected rails app has been loaded."
8
+ rescue LoadError
9
+ end
10
+ end
11
+ end
12
+
13
+ module InstanceMethods
14
+ def add_rails_executor_to_around_actions
15
+ if defined?(::Rails)
16
+ RubyClock.instance.around_actions << Proc.new do |job_proc|
17
+ ::Rails.application.executor.wrap do
18
+ job_proc.call
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,37 @@
1
+ # See https://code.jjb.cc/running-rake-tasks-from-within-ruby-on-rails-code
2
+ module RubyClock::Rake
3
+ def prepare_rake
4
+ if defined?(::Rails) && Rails.application
5
+ Rails.application.load_tasks
6
+ Rake::Task.tasks.each{|t| t.prerequisites.delete 'environment' }
7
+ @rake_mutex = Mutex.new
8
+ else
9
+ puts <<~MESSAGE
10
+ Because this is not a rails application, we do not know how to load your
11
+ rake tasks. You can do this yourself at the top of your Clockfile if you want
12
+ to run rake tasks from ruby-clock.
13
+ MESSAGE
14
+ end
15
+ end
16
+
17
+ # for tasks that don't have dependencies
18
+ def rake_execute(task)
19
+ Rake::Task[task].execute
20
+ end
21
+
22
+ # If the task doesn't share dependencies with another task,
23
+ # or if it does and you know you'll never run tasks such that any overlap
24
+ def rake_async(task)
25
+ Rake::Task[task].invoke
26
+ ensure
27
+ Rake::Task[task].reenable
28
+ Rake::Task[task].all_prerequisite_tasks.each(&:reenable)
29
+ end
30
+
31
+ # If the task has shared dependencies and you might run more than one at the same time
32
+ # This is the safest option and hence the default.
33
+ def rake(task)
34
+ @rake_mutex.synchronize { rake_async(task) }
35
+ end
36
+
37
+ end
@@ -0,0 +1,23 @@
1
+ # if we ever want to make these available at the top-level using refinements,
2
+ # like we do with the DSL, it doesn't work in Rails because Rails prepends Kernel after
3
+ # we use the refinment. Initial tests show that prepending ActiveSupport::ForkTracker::CoreExtPrivate
4
+ # works, but maybe that's not reliable or has unknown side effects
5
+ # https://stackoverflow.com/questions/74119178/
6
+
7
+ module RubyClock::Runners
8
+ def self.shell(string)
9
+ RubyClock.instance.shell(string)
10
+ end
11
+
12
+ def self.rake(string)
13
+ RubyClock.instance.rake(string)
14
+ end
15
+
16
+ def self.rake_execute(string)
17
+ RubyClock.instance.rake_execute(string)
18
+ end
19
+
20
+ def self.rake_async(string)
21
+ RubyClock.instance.rake_async(string)
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ module RubyClock::Shell
2
+ def shell_runner
3
+ @shell_runner ||= begin
4
+ require 'terrapin'
5
+ require 'posix-spawn'
6
+
7
+ unless Terrapin::CommandLine.runner.class == Terrapin::CommandLine::PosixRunner
8
+ puts <<~MESSAGE
9
+
10
+ 🤷 terrapin and posix-spawn are installed, but for some reason terrapin is
11
+ not using posix-spawn as its runner.
12
+
13
+ MESSAGE
14
+ end
15
+
16
+ puts '🐆 Using terrapin for shell commands.'
17
+ :terrapin
18
+ rescue LoadError
19
+ puts <<~MESSAGE
20
+
21
+ 🦥 Using ruby backticks for shell commands.
22
+ For better performance, install the terrapin and posix-spawn gems.
23
+ See README.md for more info.
24
+
25
+ MESSAGE
26
+ :backticks
27
+ end
28
+ end
29
+
30
+ def shell(command)
31
+ case shell_runner
32
+ when :terrapin
33
+ Terrapin::CommandLine.new(command).run
34
+ when :backticks
35
+ `#{command}`
36
+ end
37
+ end
38
+ end
@@ -1,3 +1,3 @@
1
1
  class RubyClock
2
- VERSION = "2.0.0.beta2"
2
+ VERSION = "2.0.0.beta4"
3
3
  end
data/lib/ruby-clock.rb CHANGED
@@ -1,13 +1,28 @@
1
+ require "ruby-clock/dsl"
1
2
  require "ruby-clock/version"
3
+ require "ruby-clock/rake"
4
+ require "ruby-clock/shell"
5
+ require "ruby-clock/around_actions"
6
+ require "ruby-clock/dsl"
7
+ require "ruby-clock/runners"
8
+ require "ruby-clock/rails"
2
9
  require 'rufus-scheduler'
3
10
  require 'singleton'
4
11
 
5
12
  class RubyClock
6
-
7
13
  include Singleton
14
+ include RubyClock::Rails::InstanceMethods
15
+ extend RubyClock::Rails::ClassMethods
16
+ include RubyClock::Rake
17
+ include RubyClock::Shell
18
+ include RubyClock::AroundActions
8
19
 
9
20
  attr_accessor :on_error
10
21
 
22
+ def initialize
23
+ set_up_around_actions
24
+ end
25
+
11
26
  def wait_seconds
12
27
  ENV['RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS']&.to_i || 29
13
28
  end
@@ -42,78 +57,4 @@ class RubyClock
42
57
  schedule.resume
43
58
  schedule.join
44
59
  end
45
-
46
- def prepare_rake
47
- if defined?(::Rails) && Rails.application
48
- Rails.application.load_tasks
49
- Rake::Task.tasks.each{|t| t.prerequisites.delete 'environment' }
50
- @rake_mutex = Mutex.new
51
- else
52
- puts <<~MESSAGE
53
- Because this is not a rails application, we do not know how to load your
54
- rake tasks. You can do this yourself at the top of your Clockfile if you want
55
- to run rake tasks from ruby-clock.
56
- MESSAGE
57
- end
58
- end
59
-
60
- # See https://code.jjb.cc/running-rake-tasks-from-within-ruby-on-rails-code
61
-
62
- # for tasks that don't have dependencies
63
- def rake_execute(task)
64
- Rake::Task[task].execute
65
- end
66
-
67
- # If the task doesn't share dependencies with another task,
68
- # or if it does and you know you'll never run tasks such that any overlap
69
- def rake_async(task)
70
- Rake::Task[task].invoke
71
- ensure
72
- Rake::Task[task].reenable
73
- Rake::Task[task].all_prerequisite_tasks.each(&:reenable)
74
- end
75
-
76
- # If the task has shared dependencies and you might run more than one at the same time
77
- # This is the safest option and hence the default.
78
- def rake(task)
79
- @rake_mutex.synchronize { rake_async(task) }
80
- end
81
-
82
- def shell_runner
83
- @shell_runner ||= begin
84
- require 'terrapin'
85
- require 'posix-spawn'
86
-
87
- unless Terrapin::CommandLine.runner.class == Terrapin::CommandLine::PosixRunner
88
- puts <<~MESSAGE
89
-
90
- 🤷 terrapin and posix-spawn are installed, but for some reason terrapin is
91
- not using posix-spawn as its runner.
92
-
93
- MESSAGE
94
- end
95
-
96
- puts '🐆 Using terrapin for shell commands.'
97
- :terrapin
98
- rescue LoadError
99
- puts <<~MESSAGE
100
-
101
- 🦥 Using ruby backticks for shell commands.
102
- For better performance, install the terrapin and posix-spawn gems.
103
- See README.md for more info.
104
-
105
- MESSAGE
106
- :backticks
107
- end
108
- end
109
-
110
- def shell(command)
111
- case shell_runner
112
- when :terrapin
113
- Terrapin::CommandLine.new(command).run
114
- when :backticks
115
- `#{command}`
116
- end
117
- end
118
-
119
60
  end
@@ -0,0 +1,14 @@
1
+ require 'method_source'
2
+ class Rufus::Scheduler::Job
3
+ def identifier
4
+ @identifier ||= begin
5
+ name || handler.source.split("\n").reject(&:empty?).grep_v(/#.*/)[-2].strip
6
+ rescue
7
+ begin
8
+ source_location.join('-')
9
+ rescue
10
+ 'error-calculating-job-identifier'
11
+ end
12
+ end
13
+ end
14
+ end
data/ruby-clock.gemspec CHANGED
@@ -6,8 +6,17 @@ Gem::Specification.new do |spec|
6
6
  spec.authors = ["John Bachir"]
7
7
  spec.email = ["j@jjb.cc"]
8
8
 
9
- spec.summary = 'A "clock" process for invoking ruby code within a persistent runtime'
9
+ spec.summary = 'A job scheduler which runs jobs each in their own thread in a persistent process.'
10
10
  # spec.description = %q{TODO: Write a longer description or delete this line.}
11
+ spec.post_install_message = <<~MESSAGE
12
+
13
+ If you are updating ruby-clock from 1→2, there are a few things you need to change in your Clockfile.
14
+
15
+ It's quick, easy, and fun! See instructions here:
16
+ https://github.com/jjb/ruby-clock/blob/main/CHANGELOG.md#migrating-from-ruby-clock-version-1-to-version-2
17
+
18
+ MESSAGE
19
+
11
20
  spec.homepage = "https://github.com/jjb/ruby-clock"
12
21
  spec.license = "MIT"
13
22
  spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
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.beta2
4
+ version: 2.0.0.beta4
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-15 00:00:00.000000000 Z
11
+ date: 2022-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rufus-scheduler
@@ -142,7 +142,14 @@ files:
142
142
  - example-rails-app/vendor/javascript/.keep
143
143
  - exe/clock
144
144
  - lib/ruby-clock.rb
145
+ - lib/ruby-clock/around_actions.rb
146
+ - lib/ruby-clock/dsl.rb
147
+ - lib/ruby-clock/rails.rb
148
+ - lib/ruby-clock/rake.rb
149
+ - lib/ruby-clock/runners.rb
150
+ - lib/ruby-clock/shell.rb
145
151
  - lib/ruby-clock/version.rb
152
+ - lib/rufus_monkeypatch.rb
146
153
  - release.md
147
154
  - ruby-clock.gemspec
148
155
  homepage: https://github.com/jjb/ruby-clock
@@ -151,7 +158,13 @@ licenses:
151
158
  metadata:
152
159
  homepage_uri: https://github.com/jjb/ruby-clock
153
160
  source_code_uri: https://github.com/jjb/ruby-clock
154
- post_install_message:
161
+ post_install_message: |2+
162
+
163
+ If you are updating ruby-clock from 1→2, there are a few things you need to change in your Clockfile.
164
+
165
+ It's quick, easy, and fun! See instructions here:
166
+ https://github.com/jjb/ruby-clock/blob/main/CHANGELOG.md#migrating-from-ruby-clock-version-1-to-version-2
167
+
155
168
  rdoc_options: []
156
169
  require_paths:
157
170
  - lib
@@ -169,5 +182,7 @@ requirements: []
169
182
  rubygems_version: 3.1.6
170
183
  signing_key:
171
184
  specification_version: 4
172
- summary: A "clock" process for invoking ruby code within a persistent runtime
185
+ summary: A job scheduler which runs jobs each in their own thread in a persistent
186
+ process.
173
187
  test_files: []
188
+ ...