workhorse 1.2.2 → 1.2.6
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 +4 -4
- data/.github/workflows/ruby.yml +36 -0
- data/CHANGELOG.md +23 -0
- data/LICENSE +1 -1
- data/README.md +25 -5
- data/VERSION +1 -1
- data/lib/workhorse/daemon/shell_handler.rb +6 -0
- data/lib/workhorse/daemon.rb +22 -0
- data/lib/workhorse/db_job.rb +2 -0
- data/lib/workhorse/enqueuer.rb +1 -1
- data/lib/workhorse/jobs/detect_stale_jobs_job.rb +15 -11
- data/lib/workhorse/worker.rb +14 -0
- data/lib/workhorse.rb +12 -0
- data/test/lib/test_helper.rb +1 -1
- data/workhorse.gemspec +4 -4
- metadata +4 -4
- data/.travis.yml +0 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b1cc4ec91d5c8cde5e214aff39f298f3fa9591b6693250158250fd8de87dd19
|
4
|
+
data.tar.gz: e333e77dc8bb0a24b809324a54d014f56b9373ccc0f16dc5f58052fa7bd1bbe3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: af21dcc9cf0672dc71ae1b5ec2d61e6245cf6a24fc4b599d1c21c36c06e20cbc46b59248ea0b6232589eced87305c408cbe7254e6817fdb5bb2ec294181e87a7
|
7
|
+
data.tar.gz: 368889c80a413ad8e0343a5227ba70081470931e427ca7ec7c1b1bad6cee59af2a2f9bffe31fb879f1d1a81f2233f506cb038d896dce08b2551733873c013f1f
|
@@ -0,0 +1,36 @@
|
|
1
|
+
name: Build
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
strategy:
|
13
|
+
fail-fast: false
|
14
|
+
matrix:
|
15
|
+
ruby-version: ['2.5.1', '2.6.2', '2.7.1', '3.0.1']
|
16
|
+
env:
|
17
|
+
DB_DATABASE: workhorse
|
18
|
+
DB_USER: root
|
19
|
+
DB_PASSWORD: 'root'
|
20
|
+
DB_HOST: localhost
|
21
|
+
|
22
|
+
steps:
|
23
|
+
- uses: actions/checkout@v2
|
24
|
+
- name: Set up Ruby
|
25
|
+
uses: ruby/setup-ruby@v1
|
26
|
+
with:
|
27
|
+
ruby-version: ${{ matrix.ruby-version }}
|
28
|
+
bundler-cache: true
|
29
|
+
- name: Startup database
|
30
|
+
run: |
|
31
|
+
sudo /etc/init.d/mysql start
|
32
|
+
mysql -u${{ env.DB_USER }} -p${{ env.DB_PASSWORD }} -e 'CREATE DATABASE ${{ env.DB_DATABASE }};'
|
33
|
+
- name: Run rake tests
|
34
|
+
run: bundle exec rake test TESTOPTS='--verbose'
|
35
|
+
- name: Run rubocop
|
36
|
+
run: bundle exec rubocop
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# Workhorse Changelog
|
2
2
|
|
3
|
+
## 1.2.6 - 2022-01-11
|
4
|
+
|
5
|
+
* Add daemon command `restart-logging`, which sends a `HUP` interrupt to all
|
6
|
+
Workhorse processes which in turn reopen the log files. This is particularly
|
7
|
+
useful to call after log files have been rotated, e.g. using `logrotate`.
|
8
|
+
|
9
|
+
Sitrox reference: #64690.
|
10
|
+
|
11
|
+
## 1.2.5 - 2021-11-01
|
12
|
+
|
13
|
+
* Add config settings for configuring {Workhorse::Jobs::DetectStaleJobsJob}:
|
14
|
+
|
15
|
+
* `config.stale_detection_locked_to_started_threshold`
|
16
|
+
* `config.stale_detection_run_time_threshold`
|
17
|
+
|
18
|
+
## 1.2.4 - 2021-06-08
|
19
|
+
|
20
|
+
* Add `workhorse_db_job` load hook
|
21
|
+
|
22
|
+
## 1.2.3 - 2021-02-09
|
23
|
+
|
24
|
+
* Fix warning with ruby 2.7
|
25
|
+
|
3
26
|
## 1.2.2 - 2021-01-27
|
4
27
|
|
5
28
|
* Remove unused gem dependency to `schemacop`
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[](https://github.com/sitrox/workhorse/actions/workflows/ruby.yml)
|
2
2
|
[](https://badge.fury.io/rb/workhorse)
|
3
3
|
|
4
4
|
# Workhorse
|
@@ -107,10 +107,15 @@ method `Workhorse.enqueue_op`:
|
|
107
107
|
Workhorse.enqueue_op Operations::Jobs::CleanUpDatabase, { queue: :maintenance, priority: 2 }, quiet: true
|
108
108
|
```
|
109
109
|
|
110
|
-
|
111
|
-
|
110
|
+
The first argument of the method is the Operation you want to run. Params passed in
|
111
|
+
using the second argument will be used by Workhorse and params passed using the
|
112
|
+
third argument will be used for operation instantiation at job execution, i.e.:
|
112
113
|
|
113
|
-
|
114
|
+
```ruby
|
115
|
+
Workhorse.enqueue_op <Operation Class Name>, { <Workhorse Options> }, { <RailsOps Options> }
|
116
|
+
```
|
117
|
+
|
118
|
+
If you do not want to pass any params to the operation, just omit the third hash:
|
114
119
|
|
115
120
|
```ruby
|
116
121
|
Workhorse.enqueue_op Operations::Jobs::CleanUpDatabase, queue: :maintenance, priority: 2
|
@@ -384,6 +389,21 @@ jobs database on a regular interval. Workhorse provides the job
|
|
384
389
|
`Workhorse::Jobs::CleanupSucceededJobs` for this purpose that cleans up all
|
385
390
|
succeeded jobs. You can run this using your scheduler in a specific interval.
|
386
391
|
|
392
|
+
## Load hooks
|
393
|
+
|
394
|
+
Using the load hook `:workhorse_db_job`, you can inject custom code into the
|
395
|
+
Gem-internal model class `Workhorse::DbJob`, for example:
|
396
|
+
|
397
|
+
```ruby
|
398
|
+
# config/initializers/workhorse.rb
|
399
|
+
|
400
|
+
ActiveSupport.on_load :workhorse_db_job do
|
401
|
+
# Code within this block will be run inside of the model class
|
402
|
+
# Workhorse::DbJob.
|
403
|
+
belongs_to :user
|
404
|
+
end
|
405
|
+
```
|
406
|
+
|
387
407
|
## Caveats
|
388
408
|
|
389
409
|
### Errors during polling / crashed workers
|
@@ -421,4 +441,4 @@ Please consult the [FAQ](FAQ.md).
|
|
421
441
|
|
422
442
|
## Copyright
|
423
443
|
|
424
|
-
Copyright ©
|
444
|
+
Copyright © 2017 - 2022 Sitrox. See `LICENSE` for further details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.6
|
@@ -26,6 +26,8 @@ module Workhorse
|
|
26
26
|
exit daemon.watch
|
27
27
|
when 'restart'
|
28
28
|
exit daemon.restart
|
29
|
+
when 'restart-logging'
|
30
|
+
exit daemon.restart_logging
|
29
31
|
when 'usage'
|
30
32
|
usage
|
31
33
|
exit 99
|
@@ -68,6 +70,10 @@ Options:
|
|
68
70
|
restart
|
69
71
|
Shortcut for consecutive 'stop' and 'start'.
|
70
72
|
|
73
|
+
restart-logging
|
74
|
+
Re-opens log files, useful e.g. after the log files have been moved or
|
75
|
+
removed by log rotation.
|
76
|
+
|
71
77
|
usage
|
72
78
|
Show this message
|
73
79
|
|
data/lib/workhorse/daemon.rb
CHANGED
@@ -120,6 +120,24 @@ module Workhorse
|
|
120
120
|
return start
|
121
121
|
end
|
122
122
|
|
123
|
+
def restart_logging
|
124
|
+
code = 0
|
125
|
+
|
126
|
+
for_each_worker do |worker|
|
127
|
+
pid_file, pid = read_pid(worker)
|
128
|
+
|
129
|
+
begin
|
130
|
+
Process.kill 'HUP', pid
|
131
|
+
puts "Worker (#{worker.name}) ##{worker.id}: Sent signal for restart-logging"
|
132
|
+
rescue Errno::ESRCH
|
133
|
+
warn "Worker (#{worker.name}) ##{worker.id}: Could not send signal for restart-logging, process not found"
|
134
|
+
code = 1
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
return code
|
139
|
+
end
|
140
|
+
|
123
141
|
private
|
124
142
|
|
125
143
|
def for_each_worker(&block)
|
@@ -150,6 +168,10 @@ module Workhorse
|
|
150
168
|
File.delete(pid_file)
|
151
169
|
end
|
152
170
|
|
171
|
+
def hup_worker(pid)
|
172
|
+
Process.kill('HUP', pid)
|
173
|
+
end
|
174
|
+
|
153
175
|
def process_name(worker)
|
154
176
|
if defined?(Rails)
|
155
177
|
path = Rails.root
|
data/lib/workhorse/db_job.rb
CHANGED
data/lib/workhorse/enqueuer.rb
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
module Workhorse::Jobs
|
2
|
+
# This job picks up jobs that remained `locked` or `started` (running) for
|
3
|
+
# more than a certain amount of time. If any of these jobs are found, an
|
4
|
+
# exception is thrown (which may cause a notification if you configured
|
5
|
+
# `on_exception` accordingly).
|
6
|
+
#
|
7
|
+
# The thresholds are obtained from the configuration options
|
8
|
+
# {Workhorse.stale_detection_locked_to_started_threshold
|
9
|
+
# config.stale_detection_locked_to_started_threshold} and
|
10
|
+
# {Workhorse.stale_detection_run_time_threshold
|
11
|
+
# config.stale_detection_run_time_threshold}.
|
2
12
|
class DetectStaleJobsJob
|
3
|
-
#
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
# Set this to 0 to skip this check.
|
8
|
-
# @param run_time_threshold [Integer] The maximum number of seconds
|
9
|
-
# a job is allowed to run before this job throws an exception. Set this to
|
10
|
-
# 0 to skip this check.
|
11
|
-
def initialize(locked_to_started_threshold: 3 * 60, run_time_threshold: 12 * 60)
|
12
|
-
@locked_to_started_threshold = locked_to_started_threshold
|
13
|
-
@run_time_threshold = run_time_threshold
|
13
|
+
# @private
|
14
|
+
def initialize
|
15
|
+
@locked_to_started_threshold = Workhorse.stale_detection_locked_to_started_threshold
|
16
|
+
@run_time_threshold = Workhorse.stale_detection_run_time_threshold
|
14
17
|
end
|
15
18
|
|
19
|
+
# @private
|
16
20
|
def perform
|
17
21
|
messages = []
|
18
22
|
|
data/lib/workhorse/worker.rb
CHANGED
@@ -2,6 +2,7 @@ module Workhorse
|
|
2
2
|
class Worker
|
3
3
|
LOG_LEVELS = %i[fatal error warn info debug].freeze
|
4
4
|
SHUTDOWN_SIGNALS = %w[TERM INT].freeze
|
5
|
+
LOG_REOPEN_SIGNAL = 'HUP'.freeze
|
5
6
|
|
6
7
|
attr_reader :queues
|
7
8
|
attr_reader :state
|
@@ -87,6 +88,7 @@ module Workhorse
|
|
87
88
|
log 'Started up'
|
88
89
|
|
89
90
|
trap_termination if @auto_terminate
|
91
|
+
trap_log_reopen
|
90
92
|
end
|
91
93
|
end
|
92
94
|
|
@@ -152,6 +154,18 @@ module Workhorse
|
|
152
154
|
end
|
153
155
|
end
|
154
156
|
|
157
|
+
def trap_log_reopen
|
158
|
+
Signal.trap(LOG_REOPEN_SIGNAL) do
|
159
|
+
Thread.new do
|
160
|
+
logger.reopen
|
161
|
+
|
162
|
+
if defined?(ActiveRecord::Base) && ActiveRecord::Base.logger && ActiveRecord::Base.logger != logger
|
163
|
+
ActiveRecord::Base.logger.reopen
|
164
|
+
end
|
165
|
+
end.join
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
155
169
|
def trap_termination
|
156
170
|
SHUTDOWN_SIGNALS.each do |signal|
|
157
171
|
Signal.trap(signal) do
|
data/lib/workhorse.rb
CHANGED
@@ -45,6 +45,18 @@ module Workhorse
|
|
45
45
|
mattr_accessor :perform_jobs_in_tx
|
46
46
|
self.perform_jobs_in_tx = true
|
47
47
|
|
48
|
+
# This setting is for {Workhorse::Jobs::DetectStaleJobsJob} and specifies the
|
49
|
+
# maximum number of seconds a job is allowed to stay 'locked' before this job
|
50
|
+
# throws an exception. Set this to 0 to skip this check.
|
51
|
+
mattr_accessor :stale_detection_locked_to_started_threshold
|
52
|
+
self.stale_detection_locked_to_started_threshold = 3 * 60
|
53
|
+
|
54
|
+
# This setting is for {Workhorse::Jobs::DetectStaleJobsJob} and specifies the
|
55
|
+
# maximum number of seconds a job is allowed to run before this job throws an
|
56
|
+
# exception. Set this to 0 to skip this check.
|
57
|
+
mattr_accessor :stale_detection_run_time_threshold
|
58
|
+
self.stale_detection_run_time_threshold = 12 * 60
|
59
|
+
|
48
60
|
def self.setup
|
49
61
|
yield self
|
50
62
|
end
|
data/test/lib/test_helper.rb
CHANGED
data/workhorse.gemspec
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: workhorse 1.2.
|
2
|
+
# stub: workhorse 1.2.6 ruby lib
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = "workhorse".freeze
|
6
|
-
s.version = "1.2.
|
6
|
+
s.version = "1.2.6"
|
7
7
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Sitrox".freeze]
|
11
|
-
s.date = "
|
12
|
-
s.files = [".
|
11
|
+
s.date = "2022-01-11"
|
12
|
+
s.files = [".github/workflows/ruby.yml".freeze, ".gitignore".freeze, ".releaser_config".freeze, ".rubocop.yml".freeze, "CHANGELOG.md".freeze, "FAQ.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "RUBY_VERSION".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/rubocop".freeze, "lib/active_job/queue_adapters/workhorse_adapter.rb".freeze, "lib/generators/workhorse/install_generator.rb".freeze, "lib/generators/workhorse/templates/bin/workhorse.rb".freeze, "lib/generators/workhorse/templates/config/initializers/workhorse.rb".freeze, "lib/generators/workhorse/templates/create_table_jobs.rb".freeze, "lib/workhorse.rb".freeze, "lib/workhorse/daemon.rb".freeze, "lib/workhorse/daemon/shell_handler.rb".freeze, "lib/workhorse/db_job.rb".freeze, "lib/workhorse/enqueuer.rb".freeze, "lib/workhorse/jobs/cleanup_succeeded_jobs.rb".freeze, "lib/workhorse/jobs/detect_stale_jobs_job.rb".freeze, "lib/workhorse/jobs/run_active_job.rb".freeze, "lib/workhorse/jobs/run_rails_op.rb".freeze, "lib/workhorse/performer.rb".freeze, "lib/workhorse/poller.rb".freeze, "lib/workhorse/pool.rb".freeze, "lib/workhorse/scoped_env.rb".freeze, "lib/workhorse/worker.rb".freeze, "test/active_job/queue_adapters/workhorse_adapter_test.rb".freeze, "test/lib/db_schema.rb".freeze, "test/lib/jobs.rb".freeze, "test/lib/test_helper.rb".freeze, "test/workhorse/db_job_test.rb".freeze, "test/workhorse/enqueuer_test.rb".freeze, "test/workhorse/performer_test.rb".freeze, "test/workhorse/poller_test.rb".freeze, "test/workhorse/pool_test.rb".freeze, "test/workhorse/worker_test.rb".freeze, "workhorse.gemspec".freeze]
|
13
13
|
s.rubygems_version = "3.0.3".freeze
|
14
14
|
s.summary = "Multi-threaded job backend with database queuing for ruby.".freeze
|
15
15
|
s.test_files = ["test/active_job/queue_adapters/workhorse_adapter_test.rb".freeze, "test/lib/db_schema.rb".freeze, "test/lib/jobs.rb".freeze, "test/lib/test_helper.rb".freeze, "test/workhorse/db_job_test.rb".freeze, "test/workhorse/enqueuer_test.rb".freeze, "test/workhorse/performer_test.rb".freeze, "test/workhorse/poller_test.rb".freeze, "test/workhorse/pool_test.rb".freeze, "test/workhorse/worker_test.rb".freeze]
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: workhorse
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sitrox
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -184,10 +184,10 @@ executables: []
|
|
184
184
|
extensions: []
|
185
185
|
extra_rdoc_files: []
|
186
186
|
files:
|
187
|
+
- ".github/workflows/ruby.yml"
|
187
188
|
- ".gitignore"
|
188
189
|
- ".releaser_config"
|
189
190
|
- ".rubocop.yml"
|
190
|
-
- ".travis.yml"
|
191
191
|
- CHANGELOG.md
|
192
192
|
- FAQ.md
|
193
193
|
- Gemfile
|
@@ -245,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
245
245
|
- !ruby/object:Gem::Version
|
246
246
|
version: '0'
|
247
247
|
requirements: []
|
248
|
-
rubygems_version: 3.
|
248
|
+
rubygems_version: 3.2.22
|
249
249
|
signing_key:
|
250
250
|
specification_version: 4
|
251
251
|
summary: Multi-threaded job backend with database queuing for ruby.
|