ruby-clock 0.7.0 → 0.8.0.rc1

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: 2681c0a4279cd09c1c12b8495148b426f3af51ed8620615441ad013f2e21e40a
4
- data.tar.gz: db0aea19c254edf9007dd9d1f34a8d1d9616e864972187f1345857ae6ad4f4db
3
+ metadata.gz: 77de35a13a23a83386d574ebc2ff0e71777f65b3612a9a444afd4f9ea69286bf
4
+ data.tar.gz: 95cec8207417b487dfb81fb20b9cc8147bd90200efb009cc56a8c023773979bf
5
5
  SHA512:
6
- metadata.gz: 1461d0c51349a1d635dc85dfc54a691753b48be4fcba2b687257d415d74fb8ced8b9fe15471f7940212bfd1ebf82ed8df2ccb93519f769c5c4034c0cc748a762
7
- data.tar.gz: c0120a55ef27d303c66d64f895d664f359cf0edc568fe7ddef6515e62079e99a3767b93ef1f75e83d6ca9971bec08b16fb51f34f8172d67e621045027acd3739
6
+ metadata.gz: a5585b7af51d706ffcbac3b88881c9b9c189dbc80e08867feea9ecef690dfd04957593504415bffde2c2022f69c1afdb0b30472f2466baa6bfc0dfad1264855d
7
+ data.tar.gz: b1a9aa07dfcaaf28f8d953c88f9ccc467ac199376dce674bff1b3fac7aef3a01416dd9638a40d5fd28ae23932d56e1f56b74888fdb485c4dce3dd9fa6ed579aa
data/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
+ ## 0.8.0 RC1
2
+
3
+ * fixed rare error when calculating job identifier
4
+ * nicer shutdown logging, indicating when shutdown process begins and ends
5
+ * ability to run rake tasks
6
+ * ability to run shell commands
7
+ * automatically wrap jobs with rails reloader
8
+
1
9
  ## 0.7.0
2
10
 
3
11
  * ability to specify the name of the file with job definitions, e.g. `bundle exec clock clocks/MyClockfile`
4
12
  * ability to specify the amount of time ruby-clock will wait before forcing threads to shut down
13
+
14
+ ## 0.6.0
15
+
16
+ * job identifiers
data/Gemfile.lock CHANGED
@@ -1,24 +1,30 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-clock (0.6.0)
4
+ ruby-clock (0.8.0.rc1)
5
5
  method_source
6
+ posix-spawn (~> 0.3.15)
6
7
  rufus-scheduler (~> 3.8)
8
+ terrapin (~> 0.6)
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
10
12
  specs:
13
+ climate_control (0.2.0)
11
14
  concurrent-ruby (1.1.9)
12
- et-orbi (1.2.4)
15
+ et-orbi (1.2.5)
13
16
  tzinfo
14
- fugit (1.5.0)
17
+ fugit (1.5.2)
15
18
  et-orbi (~> 1.1, >= 1.1.8)
16
19
  raabro (~> 1.4)
17
20
  method_source (1.0.0)
21
+ posix-spawn (0.3.15)
18
22
  raabro (1.4.0)
19
23
  rake (12.3.3)
20
24
  rufus-scheduler (3.8.0)
21
25
  fugit (~> 1.1, >= 1.1.6)
26
+ terrapin (0.6.0)
27
+ climate_control (>= 0.0.3, < 1.0)
22
28
  tzinfo (2.0.4)
23
29
  concurrent-ruby (~> 1.0)
24
30
 
@@ -30,4 +36,4 @@ DEPENDENCIES
30
36
  ruby-clock!
31
37
 
32
38
  BUNDLED WITH
33
- 2.1.4
39
+ 2.2.23
data/README.md CHANGED
@@ -71,6 +71,12 @@ To run your clock process in your app's environment:
71
71
 
72
72
  bundle exec rails runner bin/clock
73
73
 
74
+ To get smarter database connection management (such as in the case of a database restart or upgrade,
75
+ and maybe other benefits) and code reloading in dev (app code, not the code in Clockfile itself),
76
+ jobs are automatically wrapped in the
77
+ [rails app reloader](https://guides.rubyonrails.org/threading_and_code_execution.html).
78
+
79
+
74
80
  ### Non-Rails
75
81
 
76
82
  Require your app's code at the top of Clockfile:
@@ -122,6 +128,46 @@ You can define before, after, and around callbacks which will run for all jobs.
122
128
  Read [the rufus-scheduler documentation](https://github.com/jmettraux/rufus-scheduler/#callbacks)
123
129
  to learn how to do this. Where the documentation references `s`, you should use `schedule`.
124
130
 
131
+ ### Shell commands
132
+
133
+ You can run shell commands in your jobs. They are invoked using
134
+ [posix-spawn](https://github.com/rtomayko/posix-spawn), which means
135
+ the ruby process is not forked.
136
+
137
+ ```ruby
138
+ schedule.every '1 day' do
139
+ shell('sh scripts/process_stuff.sh')
140
+ end
141
+ ```
142
+
143
+ `shell` is a very simple convenience method which is implemented with
144
+ [terrapin](https://github.com/thoughtbot/terrapin). If you want to use other terrapin
145
+ features you can do so:
146
+
147
+ ```ruby
148
+ schedule.every '1 day' do
149
+ line = Terrapin::CommandLine.new('optimize_png', ":file")
150
+ Organization.with_new_logos.find_each do |o|
151
+ line.run(file: o.logo_file_path)
152
+ o.update!(logo_optimized: true)
153
+ end
154
+ end
155
+ ```
156
+
157
+ ### Rake tasks
158
+
159
+ You can run tasks from within the persistent runtime of ruby-clock, without
160
+ needing to shell out and start another process.
161
+
162
+ ```ruby
163
+ schedule.every '1 day' do
164
+ rake('reports:daily')
165
+ end
166
+ ```
167
+
168
+ There is also `rake_execute` and `rake_async`. See [the code](https://github.com/jjb/ruby-clock/blob/main/lib/ruby-clock.rb)
169
+ and [this article](https://code.jjb.cc/running-rake-tasks-from-within-ruby-on-rails-code) for more info.
170
+
125
171
  ### Job Identifier
126
172
 
127
173
  ruby-clock adds the `identifier` method to `Rufus::Scheduler::Job`. This method will return the job's
@@ -133,12 +179,12 @@ fallback is the line number of the job in Clockfile.
133
179
  Some examples of jobs and their identifiers:
134
180
 
135
181
  ```ruby
136
- schedule.every '1 second', name: 'my job' do |variable|
182
+ schedule.every '1 second', name: 'my job' do
137
183
  Foo.bar
138
184
  end
139
185
  # => my job
140
186
 
141
- schedule.every '1 day' do |variable|
187
+ schedule.every '1 day' do
142
188
  daily_things = Foo.setup_daily
143
189
  daily_things.process
144
190
  # TODO: figure out best time of day
@@ -146,7 +192,7 @@ end
146
192
  # => daily_things.process
147
193
 
148
194
  # n.b. ruby-clock isn't yet smart enough to remove trailing comments
149
- schedule.every '1 week' do |variable|
195
+ schedule.every '1 week' do
150
196
  weekly_things = Foo.setup_weekly
151
197
  weekly_things.process # does this work???!1~
152
198
  end
data/exe/clock CHANGED
@@ -8,9 +8,11 @@ class Rufus::Scheduler::Job
8
8
  @identifier ||= begin
9
9
  name || handler.source.split("\n").reject(&:empty?).grep_v(/#.*/)[-2].strip
10
10
  rescue
11
- source_location.join('-')
12
- rescue
13
- 'error-calculating-job-identifier'
11
+ begin
12
+ source_location.join('-')
13
+ rescue
14
+ 'error-calculating-job-identifier'
15
+ end
14
16
  end
15
17
  end
16
18
  end
@@ -18,7 +20,20 @@ end
18
20
  include RubyClock
19
21
 
20
22
  listen_to_signals
23
+ prepare_rake
24
+ schedule.pause
21
25
 
22
26
  load ARGV[0] || 'Clockfile'
23
27
 
28
+ if ::Rails
29
+ schedule.instance_eval do
30
+ @old_around_trigger = method :around_trigger
31
+ def around_trigger(job)
32
+ ::Rails.application.reloader.wrap do
33
+ @old_around_trigger.call(job){ yield }
34
+ end
35
+ end
36
+ end
37
+ end
38
+
24
39
  run_jobs
@@ -1,3 +1,3 @@
1
1
  module RubyClock
2
- VERSION = "0.7.0"
2
+ VERSION = "0.8.0.rc1"
3
3
  end
data/lib/ruby-clock.rb CHANGED
@@ -3,8 +3,10 @@ require 'rufus-scheduler'
3
3
 
4
4
  module RubyClock
5
5
  def shutdown
6
- puts "Shutting down ruby-clock 🐈️ 👋"
7
- Rufus::Scheduler.singleton.shutdown(wait: ENV['RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS']&.to_i || 29)
6
+ wait_seconds = ENV['RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS']&.to_i || 29
7
+ puts "Shutting down ruby-clock. Waiting #{wait_seconds} seconds for jobs to finish..."
8
+ schedule.shutdown(wait: wait_seconds)
9
+ puts "...done 🐈️ 👋"
8
10
  end
9
11
 
10
12
  def listen_to_signals
@@ -27,6 +29,48 @@ module RubyClock
27
29
 
28
30
  def run_jobs
29
31
  puts "Starting ruby-clock with #{schedule.jobs.size} jobs"
30
- Rufus::Scheduler.singleton.join
32
+ schedule.resume
33
+ schedule.join
31
34
  end
35
+
36
+ def prepare_rake
37
+ if defined?(::Rails) && Rails.application
38
+ Rails.application.load_tasks
39
+ Rake::Task.tasks.each{|t| t.prerequisites.delete 'environment' }
40
+ @rake_mutex = Mutex.new
41
+ else
42
+ puts <<~MESSAGE
43
+ Because this is not a rails application, we do not know how to load your
44
+ rake tasks. You can do this yourself at the top of your Clockfile if you want
45
+ to run rake tasks from ruby-cron.
46
+ MESSAGE
47
+ end
48
+ end
49
+
50
+ # See https://code.jjb.cc/running-rake-tasks-from-within-ruby-on-rails-code
51
+
52
+ # for tasks that don't have dependencies
53
+ def rake_execute(task)
54
+ Rake::Task[task].execute
55
+ end
56
+
57
+ # If the task doesn't share dependencies with another task,
58
+ # or if it does and you know you'll never run tasks such that any overlap
59
+ def rake_async(task)
60
+ Rake::Task[task].invoke
61
+ ensure
62
+ Rake::Task[task].reenable
63
+ Rake::Task[task].all_prerequisite_tasks.each(&:reenable)
64
+ end
65
+
66
+ # If the task has shared dependencies and you might run more than one at the same time
67
+ # This is the safest option and hence the default.
68
+ def rake(task)
69
+ @rake_mutex.synchronize { rake_async(task) }
70
+ end
71
+
72
+ def shell(command)
73
+ Terrapin::CommandLine.new(command).run
74
+ end
75
+
32
76
  end
data/release.md ADDED
@@ -0,0 +1,3 @@
1
+ 1. update lib/ruby-clock/version.rb
2
+ 2. update CHANGELOG.md
3
+ 3. `rake release`
data/ruby-clock.gemspec CHANGED
@@ -31,4 +31,6 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  spec.add_dependency "rufus-scheduler", '~> 3.8'
33
33
  spec.add_dependency "method_source"
34
+ spec.add_dependency "terrapin", '~> 0.6'
35
+ spec.add_dependency "posix-spawn", '~> 0.3.15'
34
36
  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: 0.7.0
4
+ version: 0.8.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Bachir
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-09-08 00:00:00.000000000 Z
11
+ date: 2021-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rufus-scheduler
@@ -38,7 +38,35 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description:
41
+ - !ruby/object:Gem::Dependency
42
+ name: terrapin
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.6'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: posix-spawn
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.3.15
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.3.15
69
+ description:
42
70
  email:
43
71
  - j@jjb.cc
44
72
  executables:
@@ -58,6 +86,7 @@ files:
58
86
  - exe/clock
59
87
  - lib/ruby-clock.rb
60
88
  - lib/ruby-clock/version.rb
89
+ - release.md
61
90
  - ruby-clock.gemspec
62
91
  homepage: https://github.com/jjb/ruby-clock
63
92
  licenses:
@@ -65,7 +94,7 @@ licenses:
65
94
  metadata:
66
95
  homepage_uri: https://github.com/jjb/ruby-clock
67
96
  source_code_uri: https://github.com/jjb/ruby-clock
68
- post_install_message:
97
+ post_install_message:
69
98
  rdoc_options: []
70
99
  require_paths:
71
100
  - lib
@@ -76,12 +105,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
76
105
  version: 2.3.0
77
106
  required_rubygems_version: !ruby/object:Gem::Requirement
78
107
  requirements:
79
- - - ">="
108
+ - - ">"
80
109
  - !ruby/object:Gem::Version
81
- version: '0'
110
+ version: 1.3.1
82
111
  requirements: []
83
112
  rubygems_version: 3.2.23
84
- signing_key:
113
+ signing_key:
85
114
  specification_version: 4
86
115
  summary: A "clock" process for invoking ruby code within a persistent runtime
87
116
  test_files: []