Skip to content

Migrate background jobs from DelayedJob to Solid Queue (#2656) - #2721

Open
stuzart wants to merge 51 commits into
mainfrom
solid-queue-2656
Open

Migrate background jobs from DelayedJob to Solid Queue (#2656)#2721
stuzart wants to merge 51 commits into
mainfrom
solid-queue-2656

Conversation

@stuzart

@stuzart stuzart commented Aug 20, 2026

Copy link
Copy Markdown
Member

Migrates SEEK's background job processing from DelayedJob to Solid Queue, and adds a Mission Control – Jobs dashboard for inspecting the queues. Closes #2656.

Solid Queue's tables live in the primary database (shared, not a separate queue DB). The delayed_job_active_record gem and its tables are retained so existing jobs can be migrated across (see the migrator below); they can be removed in 1.20.0.

What changed

  • Adapter cutoverconfig.active_job.queue_adapter flipped to :solid_queue; Solid Queue tables added via a regular migration (db/migrate/20260715145804_create_solid_queue_tables.rb).
  • Worker topology (config/queue.yml) — one worker per queue, each threads: 1 (a hard constraint while User.current_user / $authorization_checks_disabled remain process-global), feature-flag gated to match the previous per-queue setup. Started via bin/jobs; script/run_solid_queue.sh wraps it with restart-on-exit for deployment.
  • Recurring schedules (config/recurring.yml) — replaces the whenever/schedule.rb cron generation. The whenever gem is removed; a static crontab (docker/seek.crontab) fed to supercronic now covers the one OS-level shell task (the soffice reaper). Schedules documented in-file with a cron-syntax reference.
  • Historical job migratorseek:upgrade migrates any leftover delayed_jobs rows into Solid Queue, preserving serialized arguments, folding attempts into executions, and tolerating dangling GlobalIDs.
  • Admin panels — job queue stats, worker status, and the "restart background job workers" button reworked against Solid Queue's supervisor/process model.
  • Mission Control – Jobs dashboard — mounted at /jobs, gated behind SEEK's own admin auth (not the gem's HTTP Basic auth). Finished jobs retained for 14 days.
  • rake tasksjobs:work/workoff/clear/check redefined against Solid Queue.

Behaviour changes worth noting

  • The weekly subscription-digest schedule moved to 0 0 * * 0 (every Sunday). The old whenever-generated 0 0 1,8,15,22 * * left a coverage gap near month boundaries against the job's fixed 1.week.ago window — a long-standing bug, not a regression, now fixed.
  • db:sessions:batch_trim dropped (sessions live in Redis with allkeys-lru now).

Testing

Covered by test/integration/recurring_test.rb, test/unit/delayed_job_migrator_test.rb, updated admin/status tests, and new unit/functional coverage for the supervisor-pid and worker-restart edge cases.

Draft — still open

  • The delayed_job_active_record gem and its tables are retained so existing DelayedJob rows can be migrated into Solid Queue; they can be removed in 1.20.0 once no instance still needs to migrate.
  • Kept as a documented non-issue: command-based recurring tasks serialize on the single solid_queue_recurring worker thread (only effect is a few minutes of overnight status-cache staleness while the daily bioschema dump runs).

stuzart added 30 commits July 15, 2026 13:23
…ows (#2656)

Allow deploying with the adapter flipped to solid_queue and an empty
queue as its own phase, and defer migrating leftover delayed_jobs rows
to a separate, later phase.

[skip ci]
Queue tables will live in the shared database (not separate) and must
support MySQL, Postgres, and SQLite. Phase 5 migration decides how to
handle locked (requeue) vs failed (delete) delayed_jobs rows. Remaining
thread pool sizing question is resolved by the Phase 0 audit rather
than needing separate input.

[skip ci]
Audit found no issues with Rugged/git, HTTP clients, Sunspot, or image
processing, but flagged two process-global mutable state points
(User.current_user, $authorization_checks_disabled) used across
several jobs. Mitigate by running 1 thread per queue for this
migration rather than making them thread-local now. Also confirms
Ruby/Rails versions already satisfy Solid Queue's requirements.

[skip ci]
…2656)

Job classes only declare a queue name via queue_as; process/thread
topology lives entirely in config/queue.yml, so starting 1:1 with
today's per-feature-flag queues carries no cost — consolidating later
is a config-only change. Completes Phase 0.

[skip ci]
Completes Phase 1 of SOLID_QUEUE_MIGRATION_PLAN.md:

- Add solid_queue gem and a migration adding its tables to the shared
  primary database (not a separate queue database, per the Phase 0
  decision) rather than using the generator's default multi-database
  setup. Reverted the generator's premature adapter flip in
  config/environments/production.rb - that's Phase 4, not now.
- config/queue.yml: one worker per queue, gated by the same
  Seek::Config flags as Seek::Workers.active_queues, 1 thread per
  queue per the Phase 0 thread-safety findings.
- config/recurring.yml: covers the job-enqueue entries from
  config/schedule.rb, with schedules matched against the actual
  output of `bundle exec whenever` for parity. Non-job entries stay
  on whenever/cron.
- No ApplicationJob changes needed for retry/failure semantics -
  verified its rescue_from(Exception) already swallows exceptions
  inside perform_now itself, before any queue adapter sees them.

[skip ci]
- Verified the solid_queue migration produces correct tables/schema
  version on MySQL, SQLite, and Postgres via scratch databases.
- Ran the existing job unit tests (122) and a functional slice across
  git/data_files/samples controllers (390) unmodified, confirming no
  regressions from adding the gem - didn't force the whole test env
  onto queue_adapter: :solid_queue since that breaks
  ActiveJob::TestHelper's assert_enqueued_with, which requires the
  :test adapter specifically.
- Ran a real SolidQueue::Worker against jobs on all 8 queues plus a
  Rugged/git-backed job (reading a real repo's HEAD), confirming
  successful execution across multiple real threads in one process -
  validates the Phase 0 thread-safety finding empirically, not just
  by inspection. Also validated every config/recurring.yml entry
  resolves to a real job class with a valid schedule.

[skip ci]
Completes Phase 3 of SOLID_QUEUE_MIGRATION_PLAN.md. Unlike Phases 1-2,
this replaces the DelayedJob worker infra outright rather than adding
Solid Queue alongside it, so Phase 3 and Phase 4 (the adapter flip)
must ship together in the same release - after this alone, nothing
starts DelayedJob workers any more, but the adapter isn't flipped yet.

- Delete lib/seek/workers.rb and lib/tasks/seek_workers.rake, and the
  now-unused daemons gem they depended on.
- Add config/initializers/solid_queue.rb (supervisor pidfile) and
  script/run_solid_queue.sh, which runs bin/jobs in a loop and
  restarts it automatically unless signalled via its own pidfile -
  used by both Docker and non-Docker (script/update-from-git.sh,
  script/mini-update-from-git.sh) deployment paths.
- Update docker/start_workers.sh, docker/entrypoint.sh,
  docker-compose.yml, script/check_worker_pids.sh, and the Dockerfile
  accordingly.
- Update the admin "restart background job workers" button
  (AdminController#restart_job_workers, renamed) and the job queue
  admin pages to reflect Solid Queue's processes/jobs instead of
  DelayedJob's.
- Switch ApplicationStatus#refresh (backs the /application_status
  endpoint some deployments poll) to a DB-backed process count
  instead of local pidfiles, which is also safe to read from any
  container in a split multi-container deployment.
- Fix a Phase 1 oversight: config/recurring.yml was missing Solid
  Queue's own default finished-job cleanup task, needed since (unlike
  DelayedJob) it preserves finished jobs by default.
- Update AGENTS.md/CLAUDE.md's background-jobs section now rather
  than deferring to Phase 6, since the commands it documented no
  longer exist as of this phase.
config.active_job.queue_adapter is now :solid_queue, so all newly
enqueued jobs go to Solid Queue's tables. This ships together with
Phase 3's infra rework, which already switched worker
startup/monitoring/admin UI over to Solid Queue and stopped starting
DelayedJob workers. delayed_job_active_record and the delayed_jobs
table remain installed as a rollback safety net; migrating any rows
still sitting there is handled separately in Phase 5.

Verified via rails runner that ActiveJob::Base.queue_adapter resolves
to SolidQueueAdapter in development, and that job unit tests (122) and
admin/application-status functional tests (71) still pass unaffected.
Companion to SOLID_QUEUE_MIGRATION_PLAN.md - a walkthrough for
exercising the new queue/worker setup locally: starting bin/jobs,
enqueuing jobs on each queue, testing recurring jobs, using the admin
UI, and the pidfile-based stop/restart semantics.
db/schema.rb's alphabetical table order put solid_queue_jobs before
three tables with a foreign key referencing it (ready_executions,
recurring_executions, scheduled_executions). MySQL's DROP TABLE
CASCADE is a no-op, so reloading the schema onto a MySQL database that
already has it loaded (as CI's rake db:setup job does) failed trying
to drop solid_queue_jobs while those tables still held their FK.

Move solid_queue_jobs's create_table block to after all six tables
that reference it, so drop order is safe regardless of MySQL's lack
of real cascading drops. Verified against real MySQL: reproduced the
failure with two schema loads in a row, confirmed the fix, then ran
rake db:setup end-to-end successfully.
ApplicationStatus#refresh was counting every SolidQueue::Process row
(Supervisor + Dispatcher + Workers), not just workers, so the
statistics/application_status endpoint and admin page overstated how
many worker processes were running (e.g. 9 instead of 7 with one
queue's feature disabled). Filter to kind: 'Worker' only.

Also renamed the admin panel from "Solid Queue supervisor" to
"Background job workers" (users administering SEEK don't need to know
the gem name), and added a list of the currently active queues,
sourced from each live worker's metadata.
config/schedule.rb still had six job-enqueue entries that were
already migrated to config/recurring.yml in Phase 1 but never removed
here, so every deploy running `whenever --update-crontab` would
double-enqueue them: once via cron, once via Solid Queue's scheduler.
Removed them, leaving only the rake tasks and Docker-only shell
command that don't map onto recurring.yml.

Also moved three more entries (Galaxy::ToolMap.instance.refresh,
ApplicationStatus.instance.refresh, Seek::BioSchema::DataDump.generate_dumps)
into recurring.yml as command: entries - SolidQueue::RecurringJob#perform
just evals the command string, so it isn't limited to ActiveJob calls
as Phase 1 assumed.

While doing this, found that command:-only recurring.yml entries
(including the already-shipped clear_finished_jobs and
queue_timed_jobs) enqueue onto solid_queue_recurring, a queue
config/queue.yml had no worker for - so they had never actually run.
Added a worker for it. Verified live against a running supervisor
both before (job stuck) and after (job completes) the fix.

Added test/integration/recurring_test.rb covering config correctness,
cron validity, queue/worker coverage (fails without the queue.yml
fix), and end-to-end execution. Rewrote test/integration/schedule_test.rb
for the trimmed schedule.rb, asserting no runner jobs remain.
config/queue.yml's workers inherited Solid Queue's gem-level default
polling_interval (0.1s), which assumes the stock topology of one
worker polling all queues via a wildcard. Our one-worker-per-queue
topology (Phase 0's thread-safety mitigation) multiplies that into up
to 9 separate continuous polling loops - up to ~90 poll queries/second
against the DB even when everything is idle.

Raised to 1s for all queues except AUTH_LOOKUP (0.5s, the highest-
frequency, most latency-sensitive queue). Trades a small amount of job
pickup latency for a large reduction in idle polling load; doesn't
change the topology or thread-safety mitigation itself.
Comments added during the migration pointed at SOLID_QUEUE_MIGRATION_PLAN.md,
which will be removed once the migration is complete. Rewrote them to carry
their own context instead of relying on a doc that won't exist long-term.
regular_maintenance and auth_lookup_maintenance had their schedules
hardcoded to `0 */4` / `0 */8`, dropping the regular_job_offset minute
stagger that the old whenever schedule applied. whenever kept the */N
hour field but set the minute from the `at:` offset for hour-frequency
jobs, so on any instance with a non-zero offset these two jobs now
wrongly fired at minute :00 instead of the staggered minute.

Add an offset_minute helper and use it for both, and correct the
comment/tests that claimed hour-frequency jobs don't get the offset.
SolidQueue::FailedExecution#error is a JSON hash (exception_class,
message, backtrace), so rendering it directly dumped a raw Ruby hash
inspect with the whole backtrace inlined - a regression from
delayed_job's formatted last_error. Format it back into a readable
"Class: message" + backtrace string using the model's accessors.

Also eager-load :failed_execution so the per-row failure lookup no
longer issues one query per pending job.
# Conflicts:
#	config/schedule.rb
#	test/integration/schedule_test.rb
CacheOverflowCleanupJob arrived from main as a whenever runner entry. It runs
daily, so whenever applied both the hour and minute of the offset - use
offset_cron(4) to match.

Also restores schedule_test.rb, which the merge from main reverted to a version
testing runner jobs that have since moved to recurring.yml. Its assertion that
schedule.rb has no runner jobs is what guards against exactly this.
RUN_PERIOD and LifeMonitorStatusJob::PERIOD existed to feed `every X` in
config/schedule.rb. That reader is gone - the schedules now live in
config/recurring.yml, asserted by RecurringTest - leaving the constants read
only by unit tests asserting each equalled its own literal.

The grace period constants in RegularMaintenanceJob are used by perform, and
stay.
Companion to SOLID_QUEUE_MIGRATION_PLAN.md: what migrating to Sidekiq would
involve instead, grounded in this codebase (Redis allkeys-lru conflict, loss of
numeric priorities, crash durability, the shared global-state concurrency
blocker), plus an analysis of whether migrating to Sidekiq is easier from the
original DelayedJob or from the Solid Queue branch.
…ranch)

Mounts the rails/mission_control-jobs engine at /jobs to inspect and manage
Solid Queue jobs. Gated behind SEEK's existing admin authentication
(MissionControlJobsController) with the gem's default HTTP Basic auth disabled.

The auth config is set as module attributes rather than via
config.mission_control.jobs.*, since the engine copies that config into those
attributes in a before_initialize hook that runs before config/initializers/*.
…nch)

Adds a link to the Mission Control jobs dashboard from the admin index page, the
Management section of the admin General panel, and the job queue stats view.
Also relabels the stats heading to 'Total jobs waiting'.
Sets clear_finished_jobs_after to 14.days (gem default is 1.day), so finished
jobs stay visible in the admin/Mission Control dashboards for two weeks before
the hourly clear_finished_jobs task prunes them.
…2656)

Moves sitemap:refresh out of config/schedule.rb into a SitemapRefreshJob run via
config/recurring.yml (45 0 * * *, matching the old 12:45am cron time).

Removes db:sessions:batch_trim entirely: sessions now live in Redis with native
TTL expiry, so the task - which references the undefined
ActiveRecord::SessionStore::Session - is dead code that would raise if run.

The Docker-only kill-long-running-soffice.sh reaper stays on whenever/cron: it's
OS-level process reaping that should run out-of-band from the job system (and
more frequently than any maintenance job).
config/schedule.rb was down to a single task - the Docker-only
kill-long-running-soffice.sh reaper - so the whenever DSL was no longer
earning its keep. Replaced it with a static docker/seek.crontab fed
straight to supercronic; setup_and_start_cron now points at that file
instead of generating one via bundle exec whenever.

Removed the whenever/whenever-test gems, config/schedule.rb, its
integration test, and the whenever --update-crontab calls in the
update-from-git scripts. supercronic is retained, so soffice reaping
stays out-of-band from the job system. Cron is only started under
Docker, preserving the reaper's previous Docker-only behaviour.
Adds Seek::DelayedJobMigrator, run once via a new
seek:migrate_delayed_jobs_to_solid_queue upgrade task (only_once,
1.19.0), to move any rows left in the delayed_jobs table from before the
Solid Queue cutover into Solid Queue's own tables.

Pending/locked rows are re-enqueued preserving queue, run_at, priority
and attempts (attempts folded into ActiveJob executions); stale locks are
ignored since the delayed_job workers are gone. Already-failed rows are
deleted. Queued reindexing jobs (ReindexAllJob/ReindexingJob) are dropped
and the ReindexingQueue table is cleared, as the upgrade runs a full
seek:reindex_all straight after which supersedes them.

Each Solid Queue row is built directly from the raw ActiveJob payload
rather than deserialising and re-enqueuing the job: re-serialising would
resolve GlobalID arguments and raise DeserializationError - aborting the
whole migration - for any job whose referenced record has since been
deleted. Lazy deserialisation at perform time is already handled by
ApplicationJob rescue_from.
stuzart added 12 commits July 22, 2026 16:34
workoff only reported the scheduled-to-ready dispatch count, which is
zero whenever the jobs are already ready - so it looked like it had done
nothing. It now also reports how many jobs were waiting and how many
ran, counted via perform.active_job notifications. check was silent on
success, following delayed_job's convention; it now prints the state it
checked, while still exiting non-zero when jobs are overdue.
…tory (#2656)

Drop comparisons with delayed_job/whenever and references to the (deleted)
config/schedule.rb and the migration planning docs, so comments describe what
the code does now rather than what it replaced.
…2656)

The offset existed to stagger whenever's per-job `rails runner` process boots so
they didn't spike server load when firing in the same minute. Solid Queue enqueues
recurring tasks onto a shared worker pool instead of booting a process each, and
dedups across instances via the unique (task_key, run_at) index, so that stagger no
longer serves a purpose. The heavier daily jobs are still spread across 00:00-04:00
by fixed hours. Removes the now-unused regular_job_offset config setting.
…#2656)

The weekly subscription digest ran on days 1, 8, 15 and 22 of the month but
gathers activity over `1.week.ago`, so a day-of-month cadence leaves a gap near
month boundaries: activity on ~the 23rd-24th was never included in any digest,
and days 29-31 never triggered a run. Switching to "0 0 * * 0" (every Sunday)
tiles the one-week window with no gap or overlap.

Also adds a cron-syntax reference to the top of the file.
#1 (weekly digest month-boundary gap): mark fixed, and correct the note - it was not
a migration regression; whenever also emitted 0 0 1,8,15,22 * *, verified against the
gem. Fixed by moving to 0 0 * * 0 (Sunday).

#2 (recurring command serialization): record why the single-threaded
solid_queue_recurring worker is fine as-is - the only effect is a few minutes of
overnight status-cache staleness once a day, and the default queue is no better
(also threads: 1, and it would lose isolation from user-facing jobs).
…2656)

Temporary: revert to fairdom/seek:main before opening a pull request.
# Conflicts:
#	config/schedule.rb
#	lib/tasks/db.rake
…2656)

- Treat Errno::EPERM from Process.kill(0) as running, not stopped: the
  supervisor exists but is owned by another user, so it can't be signalled.
- Restart the workers by the resolved pid rather than kill -TERM $(cat pidfile),
  which fed kill an empty argument (and a confusing error) when the pidfile was
  missing; now report cleanly when no workers are running.
- Split each worker's comma-joined metadata['queues'] so the active-queue list
  and count are per-queue regardless of how queues map onto workers.
@stuzart stuzart added this to the 1.19.0 milestone Aug 20, 2026
@github-project-automation github-project-automation Bot moved this to No Status in SEEK 1.19.x Aug 20, 2026
@stuzart stuzart moved this from No Status to In Progress in SEEK 1.19.x Aug 20, 2026
AdminController parses human-readable duration settings via Chronic.parse.
chronic was only present as a transitive dependency of whenever; removing
whenever dropped it, breaking the error grouping timeout parsing.
Solid Queue adds a dedicated solid_queue_recurring worker (for the command-based
recurring tasks) with no delayed_job equivalent, so the deployment runs one more
worker process than before. Also update the wording to match the current status
message.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request migrates FAIRDOM-SEEK’s background job infrastructure from DelayedJob to Rails’ Solid Queue, adds Mission Control – Jobs for visibility/operations, and updates scheduling, admin tooling, and deployment scripts to match the new supervisor/worker model.

Changes:

  • Switch ActiveJob adapter to Solid Queue, add Solid Queue DB tables, and introduce a one-off migrator for legacy delayed_jobs.
  • Replace whenever/schedule.rb with Solid Queue recurring tasks (config/recurring.yml) and update worker topology (config/queue.yml) plus runtime scripts (bin/jobs, script/run_solid_queue.sh).
  • Update admin/status surfaces (restart button, job queue stats, application status output) and expand/adjust automated tests for the new job system.

Reviewed changes

Copilot reviewed 54 out of 56 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
test/unit/util_test.rb Adds unit coverage for Solid Queue supervisor PID detection.
test/unit/jobs/sitemap_refresh_job_test.rb Adds unit tests for new sitemap refresh job behavior/queue.
test/unit/jobs/regular_maintenance_job_test.rb Removes tests tied to old periodic constant scheduling.
test/unit/jobs/cache_overflow_cleanup_job_test.rb Removes tests tied to old periodic constant scheduling.
test/unit/jobs/auth_lookup_maintenance_job_test.rb Removes tests tied to old periodic constant scheduling.
test/unit/delayed_job_migrator_test.rb Adds coverage for one-off DelayedJob → Solid Queue migration logic.
test/unit/application_status_test.rb Updates “running jobs” semantics to Solid Queue worker processes.
test/integration/schedule_test.rb Removes Whenever schedule integration test.
test/integration/recurring_test.rb Adds integration coverage for recurring.yml validity and queue coverage.
test/functional/statistics_controller_test.rb Updates expected application status text output.
test/functional/admin_controller_test.rb Updates admin restart/stats/failed-job clearing tests to Solid Queue.
script/update-from-git.sh Updates deployment flow to stop/start Solid Queue runner instead of DJ tasks + whenever.
script/run_solid_queue.sh Adds a restart-on-exit wrapper for bin/jobs supervisor.
script/mini-update-from-git.sh Updates lightweight deploy script to signal Solid Queue supervisor PID.
script/check_worker_pids.sh Replaces per-worker pidfile checks with Solid Queue supervisor PID check.
script/check_deployment.rb Updates expected application status string for Solid Queue workers.
lib/tasks/seek_workers.rake Removes old DelayedJob worker rake task namespace.
lib/tasks/seek_upgrades.rake Adds one-off upgrade step to migrate remaining delayed_jobs.
lib/tasks/jobs.rake Redefines jobs:* rake tasks to operate against Solid Queue.
lib/tasks/db.rake Minor formatting cleanup.
lib/seek/workers.rb Removes DelayedJob worker orchestration module.
lib/seek/util.rb Adds Solid Queue supervisor PID helper for admin/scripts.
lib/seek/delayed_job_migrator.rb Implements the delayed_jobs → Solid Queue migration logic.
lib/seek/config_setting_attributes.yml Removes regular_job_offset setting (no longer used without Whenever).
Gemfile.lock Adds Solid Queue + Mission Control – Jobs dependencies; removes whenever/daemons.
Gemfile Declares solid_queue, mission_control-jobs, and adds chronic explicitly.
Dockerfile Ensures Solid Queue runner script is executable in image.
docker/start_workers.sh Switches container worker startup to Solid Queue runner.
docker/shared_functions.sh Switches cron setup to static docker crontab file.
docker/seek.crontab Adds static supercronic crontab for OS-level soffice reaping only.
docker/entrypoint.sh Starts Solid Queue runner instead of DJ workers; keeps cron startup.
docker-compose.yml Updates worker service description for Solid Queue.
db/schema.rb Adds Solid Queue tables/foreign keys and bumps schema version.
db/migrate/20260715145804_create_solid_queue_tables.rb Introduces Solid Queue schema as a standard migration.
config/schedule.rb Removes Whenever schedule definition.
config/routes.rb Mounts Mission Control – Jobs engine and updates admin restart route.
config/recurring.yml Adds recurring task schedule definitions for Solid Queue scheduler.
config/queue.yml Adds per-queue worker topology with feature-flag gating and threads=1 constraint.
config/initializers/solid_queue.rb Configures supervisor pidfile path and finished-job retention window.
config/initializers/mission_control.rb Configures Mission Control – Jobs to use SEEK admin auth (no HTTP Basic).
config/application.rb Switches ActiveJob adapter to :solid_queue.
bin/jobs Adds bin/jobs entrypoint for Solid Queue CLI.
app/views/statistics/application_status.text.erb Updates status text to report Solid Queue worker processes.
app/views/admin/stats/_job_queue.html.erb Reworks admin job queue panel to use Solid Queue jobs/failures + dashboard link.
app/views/admin/index.html.erb Adds link to job queue dashboard.
app/views/admin/_restart_buttons.html.erb Updates restart/status UI to target Solid Queue supervisor and list active queues.
app/views/admin/_general.html.erb Adds job queue dashboard link to admin nav.
app/models/application_status.rb Updates running job count logic to Solid Queue worker heartbeats.
app/jobs/sitemap_refresh_job.rb Adds Solid Queue-scheduled job to refresh sitemap + ping engines.
app/jobs/regular_maintenance_job.rb Removes RUN_PERIOD constant; schedule now defined in recurring.yml.
app/jobs/life_monitor_status_job.rb Removes PERIOD constant; schedule now defined in recurring.yml.
app/jobs/cache_overflow_cleanup_job.rb Removes RUN_PERIOD constant; schedule now defined in recurring.yml.
app/jobs/auth_lookup_maintenance_job.rb Removes RUN_PERIOD constant; schedule now defined in recurring.yml.
app/controllers/mission_control_jobs_controller.rb Adds base controller enforcing SEEK admin auth for Mission Control dashboard.
app/controllers/admin_controller.rb Replaces delayed job restart/cleanup actions with Solid Queue equivalents.
AGENTS.md Updates repo agent guidance to reflect Solid Queue commands/architecture.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread db/migrate/20260715145804_create_solid_queue_tables.rb Outdated
Comment thread lib/tasks/jobs.rake Outdated
Comment thread app/models/application_status.rb Outdated
Comment thread app/views/admin/_restart_buttons.html.erb Outdated
- Bump the Solid Queue tables migration to ActiveRecord::Migration[7.2] to match
  the rest of the app's migrations.
- Scope jobs:workoff's 'ready to run' count to the selected QUEUES so it matches
  the message.
- Fix the mis-indented closing paren in ApplicationStatus#refresh.
- Reword the empty worker-status line to 'No background job workers running' for
  consistency with its heading.
Replace the hand-rolled kill -TERM $(cat ...pid) invocations in the deployment
scripts with rake tasks:

- jobs:stop TERMs the run_solid_queue.sh runner loop (or the bare supervisor) so
  it stays down; used by update-from-git.sh.
- jobs:restart TERMs the supervisor so the runner respawns it with new code; used
  by mini-update-from-git.sh.
…pidfile (#2656)

Mirror SolidQueue.supervisor_pidfile so Seek.solid_queue_runner_pid reads the
path from config rather than hard-coding it, and cross-reference it from
script/run_solid_queue.sh, which writes the same location.
@stuzart
stuzart marked this pull request as ready for review August 24, 2026 13:49
@stuzart
stuzart requested review from fbacall and kdp-cloud August 24, 2026 13:49
@stuzart stuzart moved this from In Progress to In review in SEEK 1.19.x Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

Investigate using SolidQueue for managing the job queue

2 participants