ruby-clock 0.3.0 → 0.7.0

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: 6c02c6cf2aa2de399ec607078946ec4b83cacfbb54cc4a4e27e6180b790e7b07
4
- data.tar.gz: e0c6d50e81133d3e28e93c72f5e1f5033707fae3e812acf24188ff8377f5cf4f
3
+ metadata.gz: 2681c0a4279cd09c1c12b8495148b426f3af51ed8620615441ad013f2e21e40a
4
+ data.tar.gz: db0aea19c254edf9007dd9d1f34a8d1d9616e864972187f1345857ae6ad4f4db
5
5
  SHA512:
6
- metadata.gz: 3da2592ecc97fb84401ff49b68f7841e069d2d38e3638a8a00ea501a257bd7b89fcde9fb48ac48b0197ca1c4e2e2dc572eea79f1910421ef2f5db1e8939c6c6c
7
- data.tar.gz: 26cfcc6d5bd17035712c964c7a2325794260a8218ba223dc45a72b552d7dcd2615af22882f4af25a2a5737e4ea27ec5f1c374a8bdde82130e3c48b213b09eba2
6
+ metadata.gz: 1461d0c51349a1d635dc85dfc54a691753b48be4fcba2b687257d415d74fb8ced8b9fe15471f7940212bfd1ebf82ed8df2ccb93519f769c5c4034c0cc748a762
7
+ data.tar.gz: c0120a55ef27d303c66d64f895d664f359cf0edc568fe7ddef6515e62079e99a3767b93ef1f75e83d6ca9971bec08b16fb51f34f8172d67e621045027acd3739
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ ## 0.7.0
2
+
3
+ * ability to specify the name of the file with job definitions, e.g. `bundle exec clock clocks/MyClockfile`
4
+ * ability to specify the amount of time ruby-clock will wait before forcing threads to shut down
data/Gemfile.lock CHANGED
@@ -1,21 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-clock (0.3.0)
5
- rufus-scheduler (~> 3.7.0)
4
+ ruby-clock (0.6.0)
5
+ method_source
6
+ rufus-scheduler (~> 3.8)
6
7
 
7
8
  GEM
8
9
  remote: https://rubygems.org/
9
10
  specs:
10
- concurrent-ruby (1.1.7)
11
+ concurrent-ruby (1.1.9)
11
12
  et-orbi (1.2.4)
12
13
  tzinfo
13
- fugit (1.4.1)
14
+ fugit (1.5.0)
14
15
  et-orbi (~> 1.1, >= 1.1.8)
15
16
  raabro (~> 1.4)
17
+ method_source (1.0.0)
16
18
  raabro (1.4.0)
17
19
  rake (12.3.3)
18
- rufus-scheduler (3.7.0)
20
+ rufus-scheduler (3.8.0)
19
21
  fugit (~> 1.1, >= 1.1.6)
20
22
  tzinfo (2.0.4)
21
23
  concurrent-ruby (~> 1.0)
data/README.md CHANGED
@@ -16,6 +16,7 @@ The clock process will respond to signals INT (^c at the command line) and
16
16
  TERM (signal sent by environments such as Heroku and other PaaS's when shutting down).
17
17
  In both cases, the clock will stop running jobs and give existing jobs 29 seconds
18
18
  to stop before killing them.
19
+ You can change this number with `RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS` in the environment.
19
20
 
20
21
  ## Installation
21
22
 
@@ -55,11 +56,20 @@ To start your clock process:
55
56
 
56
57
  bundle exec clock
57
58
 
59
+ To use a file other than Clockfile for job definitions, specify it.
60
+ This will ignore Clockfile and only read jobs from clocks/MyClockfile:
61
+
62
+ bundle exec clock clocks/MyClockfile
63
+
58
64
  ### Rails
59
65
 
66
+ Install the `clock` binstub and commit to your repo.
67
+
68
+ bundle binstubs ruby-clock
69
+
60
70
  To run your clock process in your app's environment:
61
71
 
62
- bundle exec rails runner clock
72
+ bundle exec rails runner bin/clock
63
73
 
64
74
  ### Non-Rails
65
75
 
@@ -76,9 +86,23 @@ schedule.every('5 minutes') do
76
86
  Add this line to your Procfile
77
87
 
78
88
  ```
79
- clock: bundle exec rails runer clock
89
+ clock: bundle exec rails runner bin/clock
90
+ ```
91
+
92
+ You might have a main clock for general scheduled jobs, and then standalone ones
93
+ if your system has something where you want to monitor and adjust resources
94
+ for that work more precisely. Here, maybe the main clock needs a 2GB instance,
95
+ and the others each need 1GB all to themselves:
96
+
97
+ ```
98
+ clock: bundle exec rails runner bin/clock
99
+ thing_checker: bundle exec rails runner bin/clock clocks/thing_checker.rb
100
+ thing_reporter: bundle exec rails runner bin/clock clocks/thing_reporter.rb
80
101
  ```
81
102
 
103
+ Because of this feature, do I regret using "Clockfile" instead of, say, "clock.rb"? Maybe.
104
+
105
+
82
106
  ## More Config and Capabilities
83
107
 
84
108
  ### Error Handling
@@ -98,6 +122,63 @@ You can define before, after, and around callbacks which will run for all jobs.
98
122
  Read [the rufus-scheduler documentation](https://github.com/jmettraux/rufus-scheduler/#callbacks)
99
123
  to learn how to do this. Where the documentation references `s`, you should use `schedule`.
100
124
 
125
+ ### Job Identifier
126
+
127
+ ruby-clock adds the `identifier` method to `Rufus::Scheduler::Job`. This method will return the job's
128
+ [name](https://github.com/jmettraux/rufus-scheduler/#name--string) if one was given.
129
+ If a name is not given, the last non-comment code line in the job's block
130
+ will be used instead. If for some reason an error is encountered while calculating this, the next
131
+ fallback is the line number of the job in Clockfile.
132
+
133
+ Some examples of jobs and their identifiers:
134
+
135
+ ```ruby
136
+ schedule.every '1 second', name: 'my job' do |variable|
137
+ Foo.bar
138
+ end
139
+ # => my job
140
+
141
+ schedule.every '1 day' do |variable|
142
+ daily_things = Foo.setup_daily
143
+ daily_things.process
144
+ # TODO: figure out best time of day
145
+ end
146
+ # => daily_things.process
147
+
148
+ # n.b. ruby-clock isn't yet smart enough to remove trailing comments
149
+ schedule.every '1 week' do |variable|
150
+ weekly_things = Foo.setup_weekly
151
+ weekly_things.process # does this work???!1~
152
+ end
153
+ # => weekly_things.process # does this work???!1~
154
+ ```
155
+
156
+ This can be used for keeping track of job behavior in logs or a
157
+ stats tracker. For example:
158
+
159
+ ```ruby
160
+ def schedule.on_post_trigger(job, trigger_time)
161
+ duration = Time.now-trigger_time.to_t
162
+ StatsTracker.value('Clock: Job Execution Time', duration.round(2))
163
+ StatsTracker.value("Clock: Job #{job.identifier} Execution Time", duration.round(2))
164
+ StatsTracker.increment('Clock: Job Executions')
165
+ end
166
+
167
+ schedule.every '10 seconds', name: 'thread stats' do
168
+ thread_usage = Hash.new(0)
169
+ schedule.work_threads(:active).each do |t|
170
+ thread_usage[t[:rufus_scheduler_job].identifier] += 1
171
+ end
172
+ thread_usage.each do |job, count|
173
+ StatsTracker.value("Clock: Job #{job} Active Threads", count)
174
+ end
175
+
176
+ StatsTracker.value("Clock: Active Threads", schedule.work_threads(:active).size)
177
+ StatsTracker.value("Clock: Vacant Threads", schedule.work_threads(:vacant).size)
178
+ StatsTracker.value("Clock: DB Pool Size", ActiveRecord::Base.connection_pool.connections.size)
179
+ end
180
+ ```
181
+
101
182
  ### other rufus-scheduler Options
102
183
 
103
184
  All rufus-scheduler options are set to defaults. The `schedule` variable
@@ -107,6 +188,14 @@ so anything you can do on this instance, you can do in your Clockfile.
107
188
  Perhaps in the future ruby-clock will add some easier specific configuration
108
189
  capabilities for some things. Let me know if you have a request!
109
190
 
191
+ ## Syntax highlighting for Clockfile
192
+
193
+ To tell github and maybe other systems to syntax highlight Clockfile, put this in a .gitattributes file:
194
+
195
+ ```gitattributes
196
+ Clockfile linguist-language=Ruby
197
+ ```
198
+
110
199
 
111
200
  ## License
112
201
 
data/exe/clock CHANGED
@@ -1,10 +1,24 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'ruby-clock'
4
+ require 'method_source'
5
+
6
+ class Rufus::Scheduler::Job
7
+ def identifier
8
+ @identifier ||= begin
9
+ name || handler.source.split("\n").reject(&:empty?).grep_v(/#.*/)[-2].strip
10
+ rescue
11
+ source_location.join('-')
12
+ rescue
13
+ 'error-calculating-job-identifier'
14
+ end
15
+ end
16
+ end
17
+
4
18
  include RubyClock
5
19
 
6
20
  listen_to_signals
7
21
 
8
- load 'Clockfile'
22
+ load ARGV[0] || 'Clockfile'
9
23
 
10
24
  run_jobs
@@ -1,3 +1,3 @@
1
1
  module RubyClock
2
- VERSION = "0.3.0"
2
+ VERSION = "0.7.0"
3
3
  end
data/lib/ruby-clock.rb CHANGED
@@ -3,14 +3,22 @@ require 'rufus-scheduler'
3
3
 
4
4
  module RubyClock
5
5
  def shutdown
6
- puts "Shutting down 🐈️ 👋"
7
- puts Rufus::Scheduler.singleton.shutdown(wait: 29)
8
- exit
6
+ puts "Shutting down ruby-clock 🐈️ 👋"
7
+ Rufus::Scheduler.singleton.shutdown(wait: ENV['RUBY_CLOCK_SHUTDOWN_WAIT_SECONDS']&.to_i || 29)
9
8
  end
10
9
 
11
10
  def listen_to_signals
12
- Signal.trap('INT') { shutdown }
13
- Signal.trap('TERM') { shutdown }
11
+ signals = %w[INT TERM]
12
+ signals.each do |signal|
13
+ old_handler = Signal.trap(signal) do
14
+ shutdown
15
+ if old_handler.respond_to?(:call)
16
+ old_handler.call
17
+ else
18
+ exit
19
+ end
20
+ end
21
+ end
14
22
  end
15
23
 
16
24
  def schedule
@@ -18,6 +26,7 @@ module RubyClock
18
26
  end
19
27
 
20
28
  def run_jobs
29
+ puts "Starting ruby-clock with #{schedule.jobs.size} jobs"
21
30
  Rufus::Scheduler.singleton.join
22
31
  end
23
32
  end
data/ruby-clock.gemspec CHANGED
@@ -29,5 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- spec.add_dependency "rufus-scheduler", '~> 3.7.0'
32
+ spec.add_dependency "rufus-scheduler", '~> 3.8'
33
+ spec.add_dependency "method_source"
33
34
  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.3.0
4
+ version: 0.7.0
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: 2020-12-31 00:00:00.000000000 Z
11
+ date: 2021-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rufus-scheduler
@@ -16,15 +16,29 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 3.7.0
19
+ version: '3.8'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 3.7.0
27
- description:
26
+ version: '3.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: method_source
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
28
42
  email:
29
43
  - j@jjb.cc
30
44
  executables:
@@ -33,6 +47,7 @@ extensions: []
33
47
  extra_rdoc_files: []
34
48
  files:
35
49
  - ".gitignore"
50
+ - CHANGELOG.md
36
51
  - Gemfile
37
52
  - Gemfile.lock
38
53
  - LICENSE.txt
@@ -50,7 +65,7 @@ licenses:
50
65
  metadata:
51
66
  homepage_uri: https://github.com/jjb/ruby-clock
52
67
  source_code_uri: https://github.com/jjb/ruby-clock
53
- post_install_message:
68
+ post_install_message:
54
69
  rdoc_options: []
55
70
  require_paths:
56
71
  - lib
@@ -65,8 +80,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
80
  - !ruby/object:Gem::Version
66
81
  version: '0'
67
82
  requirements: []
68
- rubygems_version: 3.1.2
69
- signing_key:
83
+ rubygems_version: 3.2.23
84
+ signing_key:
70
85
  specification_version: 4
71
86
  summary: A "clock" process for invoking ruby code within a persistent runtime
72
87
  test_files: []