Solid Job Monitor - an enhancement of Mission Control Jobs
See the progress of any Solid Queue Job. Stop it if you need to.
Solid Job Monitor is designed to work with Rails and Solid Queue.
This is a fork and enhancement of Mission Control — Jobs. It keeps the same MissionControl::Jobs engine and dashboard. Jobs that never report progress keep working unchanged - so it maintains backwards compatibility with Mission Control — Jobs.
Install
Replace mission_control-jobs with this gem. The engine mount does not change.
# Gemfile
gem "solid_job_monitor"# config/routes.rb
mount MissionControl::Jobs::Engine, at: "/jobs"bundle install
rails db:migratedb:migrate creates mission_control_job_progresses. Until that table exists, progress writes are no-ops and the Stop / progress UI is hidden.
Report progress
Call progress from perform. The in-progress dashboard shows a bar with the percent written on it. Jobs that never register progress show an em dash.
Loop with a known total
class ImportRecordsJob < ApplicationJob
def perform(ids)
progress.register(total: ids.size, message: "Importing")
ids.each do |id|
import(id)
progress.increment
end
end
endregister creates the bar at 0%. Each increment updates the percent (current / total).
Set current and total yourself
class SyncPagesJob < ApplicationJob
def perform(pages)
pages.each_with_index do |page, index|
sync(page)
progress.update(current: index + 1, total: pages.size)
end
end
endYou can skip register and start with update. The bar appears on the first write.
When you only know a percentage
class DownloadJob < ApplicationJob
def perform(url)
download(url) do |percent_done|
progress.update(percent: percent_done)
end
end
endStop a job
In-progress jobs get a Stop button. It sets a flag. It does not kill the worker.
The job stops the next time it calls register, update, increment, or check_stopped!. A stopped job is discarded: it is not retried and does not appear under Failed.
Jobs that never call those methods keep running after Stop.
Long step with no increment
Use check_stopped! between slow work that does not report progress (for example a large HTTP call):
class EnrichJob < ApplicationJob
def perform(records)
progress.register(total: records.size)
records.each do |record|
progress.check_stopped!
slow_request(record)
progress.increment
end
end
endincrement / update / register already call check_stopped!, so you only need the explicit check when a single step can run for a long time.
