workhorse 1.2.16 → 1.2.17.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 +4 -4
- data/CHANGELOG.md +26 -0
- data/LICENSE +1 -1
- data/README.md +25 -1
- data/RUBY_VERSION +1 -1
- data/VERSION +1 -1
- data/lib/workhorse/daemon.rb +23 -11
- data/lib/workhorse/performer.rb +1 -2
- data/lib/workhorse/poller.rb +8 -1
- data/lib/workhorse/pool.rb +1 -0
- data/lib/workhorse/worker.rb +38 -1
- data/lib/workhorse.rb +6 -0
- data/test/lib/jobs.rb +9 -0
- data/test/lib/test_helper.rb +45 -0
- data/test/workhorse/worker_test.rb +78 -0
- data/workhorse.gemspec +18 -35
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2bcfdbfa710579ee64f436236ed5c4214404a82211ae7471513ba141e7e03eaf
|
4
|
+
data.tar.gz: 680b91c6bbdbc8473fdc454175bdf6a2f4b14a0831162ab02e92208914f69f7a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz: '
|
6
|
+
metadata.gz: 29fe50d7eb989a0d51cdcbd23adb7d42ce56fccf553448c7baf112bae2dd678a81613d593637fe6f168ff3620d9b31048abcdd0f8674b4db2244a59a82865779
|
7
|
+
data.tar.gz: '094cb3bb85f2be4bd2575f6441e2abc6ef17d522796c586dca69f864031fde2b0095bc8ce2c3d8bee6507ab799297fd8e79c86fbbadd28467495a39cc7031694'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
1
|
# Workhorse Changelog
|
2
2
|
|
3
|
+
## 1.2.17.rc1 - 2024-02-05
|
4
|
+
|
5
|
+
* Revamp memory handling:
|
6
|
+
|
7
|
+
* Change memory handling for workers to automatically shut down themselves
|
8
|
+
upon exceeding `config.max_worker_memory_mb` (if configured and > 0),
|
9
|
+
triggering the creation of a shutdown file
|
10
|
+
(`tmp/pids/workhorse.<pid>.shutdown`).
|
11
|
+
* Have the `watch` command, if scheduled, silently restart the shutdown worker
|
12
|
+
and remove the shutdown file.
|
13
|
+
* The presence of the shutdown file informs the watcher to produce output or
|
14
|
+
remain silent.
|
15
|
+
* Implement this adjustment to limit `watch` command output to error cases,
|
16
|
+
facilitating seamless cron integration for notification purposes.
|
17
|
+
|
18
|
+
Sitrox reference: #121312.
|
19
|
+
|
20
|
+
## 1.2.17.rc0 - 2024-02-05
|
21
|
+
|
22
|
+
* Add option `config.max_worker_memory_mb` for automatic restart of workers
|
23
|
+
exceeding the specified memory threshold using the `watch` command. Default is
|
24
|
+
`0`, deactivating this feature. See [memory
|
25
|
+
handling](README.md#memory-handling) for more information.
|
26
|
+
|
27
|
+
Sitrox reference: #121312.
|
28
|
+
|
3
29
|
## 1.2.16 - 2023-09-18
|
4
30
|
|
5
31
|
* Add support for `--skip-initializer` flag to install generator.
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -464,6 +464,30 @@ jobs database on a regular interval. Workhorse provides the job
|
|
464
464
|
`Workhorse::Jobs::CleanupSucceededJobs` for this purpose that cleans up all
|
465
465
|
succeeded jobs. You can run this using your scheduler in a specific interval.
|
466
466
|
|
467
|
+
## Memory handling
|
468
|
+
|
469
|
+
When a worker exceeds the memory limit specified by
|
470
|
+
`config.max_worker_memory_mb` (assuming it is configured and > 0), it initiates
|
471
|
+
a graceful shutdown process by creating a shutdown file named
|
472
|
+
`tmp/pids/workhorse.<pid>.shutdown`.
|
473
|
+
|
474
|
+
Simultaneously, the `watch` command, if scheduled, monitors the presence of this
|
475
|
+
shutdown file. Upon detecting its existence, it silently triggers the restart of
|
476
|
+
the shutdown worker and removes the shutdown file to signify that the restart
|
477
|
+
process has begun.
|
478
|
+
|
479
|
+
This mechanism ensures that workers are automatically restarted without manual
|
480
|
+
intervention when memory limits are exceeded.
|
481
|
+
|
482
|
+
Example configuration:
|
483
|
+
|
484
|
+
```ruby
|
485
|
+
# config/initializers/workhorse.rb
|
486
|
+
Workhorse.setup do |config|
|
487
|
+
config.max_worker_memory_mb = 512 # Set the memory threshold to 512 megabytes
|
488
|
+
end
|
489
|
+
```
|
490
|
+
|
467
491
|
## Load hooks
|
468
492
|
|
469
493
|
Using the load hook `:workhorse_db_job`, you can inject custom code into the
|
@@ -540,4 +564,4 @@ Please consult the [FAQ](FAQ.md).
|
|
540
564
|
|
541
565
|
## Copyright
|
542
566
|
|
543
|
-
Copyright © 2017 -
|
567
|
+
Copyright © 2017 - 2024 Sitrox. See `LICENSE` for further details.
|
data/RUBY_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-2.
|
1
|
+
ruby-3.2.1-p31
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.17.rc1
|
data/lib/workhorse/daemon.rb
CHANGED
@@ -46,15 +46,20 @@ module Workhorse
|
|
46
46
|
code = 0
|
47
47
|
|
48
48
|
for_each_worker do |worker|
|
49
|
-
pid_file, pid = read_pid(worker)
|
49
|
+
pid_file, pid, active = read_pid(worker)
|
50
50
|
|
51
|
-
if pid_file && pid
|
51
|
+
if pid_file && pid && active
|
52
52
|
warn "Worker ##{worker.id} (#{worker.name}): Already started (PID #{pid})" unless quiet
|
53
53
|
code = 2
|
54
54
|
elsif pid_file
|
55
55
|
File.delete pid_file
|
56
|
-
|
56
|
+
|
57
|
+
shutdown_file = pid ? Workhorse::Worker.shutdown_file_for(pid) : nil
|
58
|
+
shutdown_file = nil if shutdown_file && !File.exist?(shutdown_file)
|
59
|
+
|
60
|
+
puts "Worker ##{worker.id} (#{worker.name}): Starting (stale pid file)" unless quiet || shutdown_file
|
57
61
|
start_worker worker
|
62
|
+
FileUtils.rm(shutdown_file) if shutdown_file
|
58
63
|
else
|
59
64
|
warn "Worker ##{worker.id} (#{worker.name}): Starting" unless quiet
|
60
65
|
start_worker worker
|
@@ -68,9 +73,9 @@ module Workhorse
|
|
68
73
|
code = 0
|
69
74
|
|
70
75
|
for_each_worker do |worker|
|
71
|
-
pid_file, pid = read_pid(worker)
|
76
|
+
pid_file, pid, active = read_pid(worker)
|
72
77
|
|
73
|
-
if pid_file && pid
|
78
|
+
if pid_file && pid && active
|
74
79
|
puts "Worker (#{worker.name}) ##{worker.id}: Stopping"
|
75
80
|
stop_worker pid_file, pid, kill: kill
|
76
81
|
elsif pid_file
|
@@ -89,9 +94,9 @@ module Workhorse
|
|
89
94
|
code = 0
|
90
95
|
|
91
96
|
for_each_worker do |worker|
|
92
|
-
pid_file, pid = read_pid(worker)
|
97
|
+
pid_file, pid, active = read_pid(worker)
|
93
98
|
|
94
|
-
if pid_file && pid
|
99
|
+
if pid_file && pid && active
|
95
100
|
puts "Worker ##{worker.id} (#{worker.name}): Running" unless quiet
|
96
101
|
elsif pid_file
|
97
102
|
warn "Worker ##{worker.id} (#{worker.name}): Not running (stale PID file)" unless quiet
|
@@ -128,7 +133,9 @@ module Workhorse
|
|
128
133
|
code = 0
|
129
134
|
|
130
135
|
for_each_worker do |worker|
|
131
|
-
_pid_file, pid = read_pid(worker)
|
136
|
+
_pid_file, pid, active = read_pid(worker)
|
137
|
+
|
138
|
+
next unless pid && active
|
132
139
|
|
133
140
|
begin
|
134
141
|
Process.kill 'HUP', pid
|
@@ -209,16 +216,21 @@ module Workhorse
|
|
209
216
|
|
210
217
|
def read_pid(worker)
|
211
218
|
file = pid_file_for(worker)
|
219
|
+
pid = nil
|
220
|
+
active = false
|
212
221
|
|
213
222
|
if File.exist?(file)
|
214
223
|
raw_pid = File.read(file)
|
215
|
-
return nil, nil if raw_pid.blank?
|
216
224
|
|
217
|
-
|
218
|
-
|
225
|
+
unless raw_pid.blank?
|
226
|
+
pid = Integer(raw_pid)
|
227
|
+
active = process?(pid)
|
228
|
+
end
|
219
229
|
else
|
220
230
|
return nil, nil
|
221
231
|
end
|
232
|
+
|
233
|
+
return file, pid, active
|
222
234
|
end
|
223
235
|
end
|
224
236
|
end
|
data/lib/workhorse/performer.rb
CHANGED
@@ -22,7 +22,7 @@ module Workhorse
|
|
22
22
|
Thread.current[:workhorse_current_performer] = self
|
23
23
|
|
24
24
|
ActiveRecord::Base.connection_pool.with_connection do
|
25
|
-
if defined?(Rails) && Rails.application && Rails.application.respond_to?(:executor)
|
25
|
+
if defined?(Rails) && Rails.respond_to?(:application) && Rails.application && Rails.application.respond_to?(:executor)
|
26
26
|
Rails.application.executor.wrap do
|
27
27
|
perform_wrapped
|
28
28
|
end
|
@@ -63,7 +63,6 @@ module Workhorse
|
|
63
63
|
|
64
64
|
inner_job_class = deserialized_job.try(:job_class) || deserialized_job.class
|
65
65
|
skip_tx = inner_job_class.try(:skip_tx?)
|
66
|
-
log "SKIP TX: #{skip_tx.inspect}".red, :error
|
67
66
|
|
68
67
|
if Workhorse.perform_jobs_in_tx && !skip_tx
|
69
68
|
Workhorse.tx_callback.call do
|
data/lib/workhorse/poller.rb
CHANGED
@@ -9,7 +9,7 @@ module Workhorse
|
|
9
9
|
attr_reader :worker
|
10
10
|
attr_reader :table
|
11
11
|
|
12
|
-
def initialize(worker)
|
12
|
+
def initialize(worker, before_poll = proc { true })
|
13
13
|
@worker = worker
|
14
14
|
@running = false
|
15
15
|
@table = Workhorse::DbJob.arel_table
|
@@ -17,6 +17,7 @@ module Workhorse
|
|
17
17
|
@instant_repoll = Concurrent::AtomicBoolean.new(false)
|
18
18
|
@global_lock_fails = 0
|
19
19
|
@max_global_lock_fails_reached = false
|
20
|
+
@before_poll = before_poll
|
20
21
|
end
|
21
22
|
|
22
23
|
def running?
|
@@ -34,6 +35,12 @@ module Workhorse
|
|
34
35
|
break unless running?
|
35
36
|
|
36
37
|
begin
|
38
|
+
unless @before_poll.call
|
39
|
+
Thread.new { worker.shutdown }
|
40
|
+
sleep
|
41
|
+
next
|
42
|
+
end
|
43
|
+
|
37
44
|
poll
|
38
45
|
sleep
|
39
46
|
rescue Exception => e
|
data/lib/workhorse/pool.rb
CHANGED
data/lib/workhorse/worker.rb
CHANGED
@@ -20,6 +20,12 @@ module Workhorse
|
|
20
20
|
worker.wait
|
21
21
|
end
|
22
22
|
|
23
|
+
# @private
|
24
|
+
def self.shutdown_file_for(pid)
|
25
|
+
return nil unless defined?(Rails)
|
26
|
+
Rails.root.join('tmp', 'pids', "workhorse.#{pid}.shutdown")
|
27
|
+
end
|
28
|
+
|
23
29
|
# Instantiates a new worker. The worker is not automatically started.
|
24
30
|
#
|
25
31
|
# @param queues [Array] The queues you want this worker to process. If an
|
@@ -51,7 +57,7 @@ module Workhorse
|
|
51
57
|
|
52
58
|
@mutex = Mutex.new
|
53
59
|
@pool = Pool.new(@pool_size)
|
54
|
-
@poller = Workhorse::Poller.new(self)
|
60
|
+
@poller = Workhorse::Poller.new(self, proc { check_memory })
|
55
61
|
@logger = logger
|
56
62
|
|
57
63
|
unless (@polling_interval / 0.1).round(2).modulo(1).zero?
|
@@ -155,6 +161,37 @@ module Workhorse
|
|
155
161
|
|
156
162
|
private
|
157
163
|
|
164
|
+
def check_memory
|
165
|
+
mem = current_memory_consumption
|
166
|
+
|
167
|
+
unless mem
|
168
|
+
log "Could not determine memory consumption of worker with pid #{pid}"
|
169
|
+
return false
|
170
|
+
end
|
171
|
+
|
172
|
+
max = Workhorse.max_worker_memory_mb
|
173
|
+
exceeded = max > 0 && current_memory_consumption > max
|
174
|
+
|
175
|
+
return true unless exceeded
|
176
|
+
|
177
|
+
if defined?(Rails)
|
178
|
+
FileUtils.touch self.class.shutdown_file_for(pid)
|
179
|
+
end
|
180
|
+
|
181
|
+
log "Worker process #{id.inspect} memory consumption (RSS) of #{mem}MB exceeds "\
|
182
|
+
"configured per-worker limit of #{max}MB and is now being shut down. Make sure "\
|
183
|
+
'that your worker processes are watched (e.g. using the "watch"-command) for ' \
|
184
|
+
'this worker to be restarted automatically.'
|
185
|
+
|
186
|
+
return false
|
187
|
+
end
|
188
|
+
|
189
|
+
def current_memory_consumption
|
190
|
+
mem = `ps -p #{pid} -o rss=`&.strip
|
191
|
+
return nil if mem.blank?
|
192
|
+
return mem.to_i / 1024
|
193
|
+
end
|
194
|
+
|
158
195
|
def check_rails_env
|
159
196
|
unless Rails.env.production?
|
160
197
|
warn 'WARNING: Always run workhorse workers in production environment. Other environments can lead to unexpected behavior.'
|
data/lib/workhorse.rb
CHANGED
@@ -75,6 +75,12 @@ module Workhorse
|
|
75
75
|
mattr_accessor :stale_detection_run_time_threshold
|
76
76
|
self.stale_detection_run_time_threshold = 12 * 60
|
77
77
|
|
78
|
+
# Maximum memory for a worker in MB. If this memory limit (RSS / resident
|
79
|
+
# size) is reached for a worker process, the 'watch' command will restart said
|
80
|
+
# worker. Set this to 0 disable this feature.
|
81
|
+
mattr_accessor :max_worker_memory_mb
|
82
|
+
self.max_worker_memory_mb = 0
|
83
|
+
|
78
84
|
def self.setup
|
79
85
|
yield self
|
80
86
|
end
|
data/test/lib/jobs.rb
CHANGED
@@ -36,6 +36,15 @@ class SyntaxErrorJob
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
class MemHungryJob
|
40
|
+
class_attribute :data
|
41
|
+
|
42
|
+
# Should consume roughly 1GB of memory.
|
43
|
+
def perform
|
44
|
+
self.class.data = 'x' * 250.megabytes
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
39
48
|
class DummyRailsOpsOp
|
40
49
|
class_attribute :results
|
41
50
|
self.results = Concurrent::Array.new
|
data/test/lib/test_helper.rb
CHANGED
@@ -5,8 +5,33 @@ require 'pry'
|
|
5
5
|
require 'colorize'
|
6
6
|
require 'mysql2'
|
7
7
|
require 'benchmark'
|
8
|
+
require 'concurrent'
|
8
9
|
require 'jobs'
|
9
10
|
|
11
|
+
class MockRailsEnv < String
|
12
|
+
def production?
|
13
|
+
self == 'production'
|
14
|
+
end
|
15
|
+
|
16
|
+
def test?
|
17
|
+
self == 'test'
|
18
|
+
end
|
19
|
+
|
20
|
+
def development?
|
21
|
+
self == 'development'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class Rails
|
26
|
+
def self.root
|
27
|
+
Pathname.new(File.expand_path(File.join(File.dirname(__FILE__), '../../')))
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.env
|
31
|
+
MockRailsEnv.new('production')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
10
35
|
class WorkhorseTest < ActiveSupport::TestCase
|
11
36
|
def setup
|
12
37
|
Workhorse::DbJob.delete_all
|
@@ -31,6 +56,14 @@ class WorkhorseTest < ActiveSupport::TestCase
|
|
31
56
|
end
|
32
57
|
end
|
33
58
|
|
59
|
+
def work_until(max: 50, interval: 0.1, **options, &block)
|
60
|
+
w = Workhorse::Worker.new(**options)
|
61
|
+
w.start
|
62
|
+
return with_retries(max, interval: interval, &block)
|
63
|
+
ensure
|
64
|
+
w.shutdown
|
65
|
+
end
|
66
|
+
|
34
67
|
def with_worker(options = {})
|
35
68
|
w = Workhorse::Worker.new(**options)
|
36
69
|
w.start
|
@@ -40,6 +73,18 @@ class WorkhorseTest < ActiveSupport::TestCase
|
|
40
73
|
w.shutdown
|
41
74
|
end
|
42
75
|
end
|
76
|
+
|
77
|
+
def with_retries(max = 50, interval: 0.1, &_block)
|
78
|
+
runs = 0
|
79
|
+
|
80
|
+
loop do
|
81
|
+
return yield
|
82
|
+
rescue Minitest::Assertion => e
|
83
|
+
fail if runs > max
|
84
|
+
sleep interval
|
85
|
+
runs += 1
|
86
|
+
end
|
87
|
+
end
|
43
88
|
end
|
44
89
|
|
45
90
|
ActiveRecord::Base.establish_connection(
|
@@ -180,8 +180,86 @@ class Workhorse::WorkerTest < WorkhorseTest
|
|
180
180
|
assert_equal 'waiting', jobs[1].state
|
181
181
|
end
|
182
182
|
|
183
|
+
def test_controlled_shutdown
|
184
|
+
remove_pids!
|
185
|
+
|
186
|
+
Workhorse.max_worker_memory_mb = 50
|
187
|
+
|
188
|
+
daemon = start_daemon
|
189
|
+
|
190
|
+
pid = with_retries do
|
191
|
+
pid = daemon.workers.first.pid
|
192
|
+
assert_process(pid)
|
193
|
+
pid
|
194
|
+
end
|
195
|
+
|
196
|
+
10.times do
|
197
|
+
Workhorse.enqueue BasicJob.new(sleep_time: 0.1)
|
198
|
+
|
199
|
+
with_retries do
|
200
|
+
assert_equal 'succeeded', Workhorse::DbJob.first.state
|
201
|
+
Workhorse::DbJob.delete_all
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
Workhorse.enqueue MemHungryJob.new
|
206
|
+
|
207
|
+
with_retries do
|
208
|
+
assert_equal 'succeeded', Workhorse::DbJob.first.state
|
209
|
+
|
210
|
+
assert File.exist?("tmp/pids/workhorse.#{pid}.shutdown")
|
211
|
+
assert_not_process pid
|
212
|
+
end
|
213
|
+
|
214
|
+
daemon.watch
|
215
|
+
|
216
|
+
with_retries do
|
217
|
+
assert_not File.exist?("tmp/pids/workhorse.#{pid}.shutdown")
|
218
|
+
end
|
219
|
+
ensure
|
220
|
+
daemon.stop
|
221
|
+
Workhorse.max_worker_memory_mb = 0
|
222
|
+
end
|
223
|
+
|
183
224
|
private
|
184
225
|
|
226
|
+
def remove_pids!
|
227
|
+
Dir[Rails.root.join('tmp', 'pids', '*')].each do |file|
|
228
|
+
FileUtils.rm file
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
def start_daemon
|
233
|
+
daemon = Workhorse::Daemon.new(pidfile: 'tmp/pids/test%s.pid') do |d|
|
234
|
+
d.worker 'Test Worker' do
|
235
|
+
begin
|
236
|
+
Workhorse::Worker.start_and_wait(
|
237
|
+
pool_size: 1,
|
238
|
+
polling_interval: 0.1,
|
239
|
+
logger: ActiveSupport::Logger.new('tmp/log.log')
|
240
|
+
)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
daemon.start
|
245
|
+
return daemon
|
246
|
+
end
|
247
|
+
|
248
|
+
def assert_process(pid)
|
249
|
+
assert process?(pid), "Process #{pid} expected to be running"
|
250
|
+
end
|
251
|
+
|
252
|
+
def assert_not_process(pid)
|
253
|
+
assert_not process?(pid), "Process #{pid} expected to be stopped"
|
254
|
+
end
|
255
|
+
|
256
|
+
def process?(pid)
|
257
|
+
Process.kill(0, pid)
|
258
|
+
true
|
259
|
+
rescue Errno::EPERM, Errno::ESRCH
|
260
|
+
false
|
261
|
+
end
|
262
|
+
|
185
263
|
def enqueue_in_multiple_queues
|
186
264
|
Workhorse.enqueue BasicJob.new(some_param: nil)
|
187
265
|
Workhorse.enqueue BasicJob.new(some_param: :q1), queue: :q1
|
data/workhorse.gemspec
CHANGED
@@ -1,48 +1,31 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: workhorse 1.2.
|
2
|
+
# stub: workhorse 1.2.17.rc1 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.17.rc1"
|
7
7
|
|
8
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
|
9
9
|
s.require_paths = ["lib".freeze]
|
10
10
|
s.authors = ["Sitrox".freeze]
|
11
|
-
s.date = "
|
11
|
+
s.date = "2024-02-08"
|
12
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/active_job_extension.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
|
-
s.rubygems_version = "3.
|
13
|
+
s.rubygems_version = "3.4.6".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]
|
16
16
|
|
17
|
-
|
18
|
-
s.specification_version = 4
|
19
|
-
end
|
17
|
+
s.specification_version = 4
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
s.add_runtime_dependency(%q<concurrent-ruby>.freeze, [">= 0"])
|
34
|
-
else
|
35
|
-
s.add_dependency(%q<bundler>.freeze, [">= 0"])
|
36
|
-
s.add_dependency(%q<rake>.freeze, [">= 0"])
|
37
|
-
s.add_dependency(%q<rubocop>.freeze, ["~> 1.28.0"])
|
38
|
-
s.add_dependency(%q<minitest>.freeze, [">= 0"])
|
39
|
-
s.add_dependency(%q<mysql2>.freeze, [">= 0"])
|
40
|
-
s.add_dependency(%q<colorize>.freeze, [">= 0"])
|
41
|
-
s.add_dependency(%q<benchmark-ips>.freeze, [">= 0"])
|
42
|
-
s.add_dependency(%q<activejob>.freeze, [">= 0"])
|
43
|
-
s.add_dependency(%q<pry>.freeze, [">= 0"])
|
44
|
-
s.add_dependency(%q<activesupport>.freeze, [">= 0"])
|
45
|
-
s.add_dependency(%q<activerecord>.freeze, [">= 0"])
|
46
|
-
s.add_dependency(%q<concurrent-ruby>.freeze, [">= 0"])
|
47
|
-
end
|
19
|
+
s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
|
20
|
+
s.add_development_dependency(%q<rake>.freeze, [">= 0"])
|
21
|
+
s.add_development_dependency(%q<rubocop>.freeze, ["~> 1.28.0"])
|
22
|
+
s.add_development_dependency(%q<minitest>.freeze, [">= 0"])
|
23
|
+
s.add_development_dependency(%q<mysql2>.freeze, [">= 0"])
|
24
|
+
s.add_development_dependency(%q<colorize>.freeze, [">= 0"])
|
25
|
+
s.add_development_dependency(%q<benchmark-ips>.freeze, [">= 0"])
|
26
|
+
s.add_development_dependency(%q<activejob>.freeze, [">= 0"])
|
27
|
+
s.add_development_dependency(%q<pry>.freeze, [">= 0"])
|
28
|
+
s.add_runtime_dependency(%q<activesupport>.freeze, [">= 0"])
|
29
|
+
s.add_runtime_dependency(%q<activerecord>.freeze, [">= 0"])
|
30
|
+
s.add_runtime_dependency(%q<concurrent-ruby>.freeze, [">= 0"])
|
48
31
|
end
|
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.17.rc1
|
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: 2024-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -242,11 +242,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
242
242
|
version: '0'
|
243
243
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
244
244
|
requirements:
|
245
|
-
- - "
|
245
|
+
- - ">"
|
246
246
|
- !ruby/object:Gem::Version
|
247
|
-
version:
|
247
|
+
version: 1.3.1
|
248
248
|
requirements: []
|
249
|
-
rubygems_version: 3.4.
|
249
|
+
rubygems_version: 3.4.10
|
250
250
|
signing_key:
|
251
251
|
specification_version: 4
|
252
252
|
summary: Multi-threaded job backend with database queuing for ruby.
|