Releases: eclectic-coding/solid_queue_web
v1.5.0
Added
- Admin audit log — every discard, retry, pause, and resume action is recorded to a
solid_queue_web_audit_eventstable; viewable at/jobs/auditwith action/actor/queue filters and CSV export; identity captured via the optionalSolidQueueWeb.current_actorconfig block; table created viarails generate solid_queue_web:install:migrations
v1.4.0
Added
- Slow job webhook alert — set
alert_slow_job_count_threshold(integer) to fire a webhook whenever the number of currently-running slow jobs meets or exceeds the configured count; requiresslow_job_thresholdto define what "slow" means; uses the samealert_webhook_urlandalert_webhook_cooldownsettings as other alert types; event nameslow_job_threshold_exceeded - Stale process webhook alert — set
alert_stale_process_threshold(integer) to fire a webhook whenever the number of stale workers meets or exceeds the configured count; a process is stale when its heartbeat has not been updated withinSolidQueue.process_alive_threshold; uses the samealert_webhook_urlandalert_webhook_cooldownsettings; event namestale_process_detected - Job wait time column — the Running tab now shows a "Wait Time" column displaying how long each claimed job waited in the queue from enqueue to pickup; also included as
wait_time_secondsin the CSV export for the claimed status - Eliminate N+1 queries on the queues index —
queue.sizeandqueue.paused?previously fired one query each per queue; both are now pre-computed in the controller with single batch aggregations (GROUP BY queue_namefor sizes, onePausequery for paused state), reducing query count from O(2N+constant) to O(constant) regardless of queue count
v1.3.0
Added
-
Sticky filter preferences — last-used status tab (Jobs) and time-period pill (Jobs, Failed Jobs, History) are persisted to
localStorage; revisiting a page via the nav link restores the previous filter automatically; clicking "All" clears the saved period; implemented as a lightweight Stimulus controller (FiltersController) with no server-side changes -
Configurable display timezone —
SolidQueueWeb.configure { |c| c.time_zone = "America/New_York" }renders all dashboard timestamps in the configured zone rather than UTC; usesin_time_zonefrom ActiveSupport; defaults to UTC when not set; aformat_timestamphelper centralises all timestamp formatting across jobs, failed jobs, history, search, queues, recurring tasks, and the scheduled-job turbo stream update -
Sortable table columns — Jobs, Failed Jobs, and History tables now support server-side sorting via
?sort=and?direction=params; click any column header to sort ascending or descending; sort state is preserved across filter changes, status tab switches, and period buttons; asort_header_thhelper generates accessible<th>elements witharia-sortand direction indicators (↑/↓)
v1.2.0
Added
-
p99 and standard deviation columns in performance analytics —
JobPerformanceStatsnow computes a 99th percentile and population standard deviation for each job class; both columns appear in the Performance table between p95 and Min; high std dev surfaces inconsistent jobs worth investigating -
Failed job trend chart — a "Failures — Last 12 Hours" bar chart card on the dashboard shows how many jobs failed per hour over the last 12 hours; bars are red (distinct from the blue throughput and purple queue depth charts); header shows the total failure count for the window; empty state shown when no failures exist in the period
-
Error frequency report — a new Error Summary page (
/jobs/failed_jobs/errors) groups all failed jobs by error class and message prefix, shows a count per group, and displays a sample backtrace (first 10 lines) in an expandable<details>element; groups are sorted by count descending so the most common errors appear first; accessible via an "Error Summary" button on the Failed Jobs page
v1.1.0
Added
- Queue depth alert —
alert_queue_thresholdsaccepts a hash ofqueue_name => ready_job_count; a webhook fires when any configured queue's ready count meets or exceeds its threshold; cooldown is tracked independently per queue so a busy queue doesn't suppress alerts for others; uses the samealert_webhook_urlendpoint(s) withevent: "queue_depth_threshold_exceeded"andqueue_name,depth, andthresholdfields in the payload - Multiple webhook targets —
alert_webhook_urlnow accepts an array of URL strings; all configured endpoints receive the same payload when the failure threshold is exceeded; a failure posting to one URL is logged and skipped without blocking the remaining targets - Retry failed job with modified arguments — the Arguments card on the job detail page becomes an editable textarea for failed jobs; editing the JSON and clicking "Retry with these arguments" updates the job record and retries in one step; invalid JSON redirects back with an error message without touching the failed execution
v1.0.0
Added
- Bulk scheduled job actions — a "Run All Now" button on the Scheduled tab back-dates all scheduled executions in a single
update_allcall, causing SolidQueue's dispatcher to pick them up immediately; respects the active period filter so only jobs within the current window are promoted - Priority filter — a
?priority=Nparam on the jobs index narrows the list to a specific integer priority value; a select dropdown appears in the search bar when multiple distinct priorities exist in the current status; priority is preserved across status tab switches, period changes, and search; Discard All also respects the active priority filter - Performance analytics — a new Performance page (
/jobs/performance) shows per-job-class statistics derived from the history table: run count, average duration, p50, p95, min, and max; rows are sorted by p95 descending so the slowest classes appear first; a period filter (1h / 24h / 7d / All) scopes the dataset; each class name links to the History page pre-filtered to that class; business logic lives in aJobPerformanceStatsservice using a single pluck query with Ruby-side aggregation for DB-agnostic percentile computation - Metrics / health endpoint —
GET /jobs/metrics.jsonreturns a JSON document with job counts (ready,scheduled,claimed,blocked,failed), throughput (completed_1h,completed_24h), per-queue depth and pause state, and process health (total,healthy,stale,by_kind); whenslow_job_thresholdis configured, aslow_jobscount is also included; the endpoint goes through the same authentication andconnects_tomiddleware as all other routes - Recurring task "Run Now" — a "Run Now" button on the Recurring Tasks page triggers
task.enqueue(at: Time.current)to enqueue the job immediately without waiting for its next scheduled run; SolidQueue'sRecurringExecutiondeduplication prevents double-enqueuing - Read replica support — when
connects_tois set to{ reading: <role>, writing: <role> }, the engine automatically routes GET requests to the reading role and mutating requests (POST/DELETE/PATCH) to the writing role viaActiveRecord::Base.connected_to(role:); passing any other hash (e.g.{ role: :writing },{ shard: :name }) falls through toconnected_todirectly; defaults tonilso single-database setups are unaffected - Webhook alert config —
alert_webhook_urlandalert_failure_thresholdsettings POST a JSON payload (event,failure_count,threshold,fired_at) to any URL when the failed job count meets or exceeds the threshold; fires asynchronously in a background thread so dashboard requests are never blocked; a configurablealert_webhook_cooldown(default 3600 s) prevents repeated alerts while the count stays elevated; HTTP errors are logged and swallowed - Bulk retry with delay — "+5s", "+10s", "+30s", and "+1m" stagger buttons on the Failed Jobs page retry all matched jobs with a configurable interval between each; the first job runs immediately, subsequent jobs are scheduled at incremental offsets; uses per-execution
retrysoscheduled_atis respected by SolidQueue's dispatcher; buttons only appear when more than one job is present - Scheduled job management — "Run Now" promotes a scheduled job to run immediately by back-dating its
scheduled_at; "+1h", "+24h", and "+7d" buttons pushscheduled_atforward by the chosen offset; both actions update the execution and the underlying job record; Turbo Stream responses remove the row on "Run Now" and update thescheduled_atcell in place on postpone
v0.9.0
Added
- Failure rate sparkline per queue — a mini 12-bar chart in the Queues table shows the percentage of jobs that failed (vs. completed) in each of the last 12 hours; bars are red, sized proportionally to the failure rate (0–100 %), and include a tooltip with the hour label and exact percentage; empty hours render as a faint border-colored bar; queues with no activity in the last 12 hours show "—"
- Queue depth trend — a "Queue Depth — Last 12 Hours" card on the dashboard shows estimated queue depth at 12 hourly snapshots; depth at time T is the count of jobs created before T that had not yet finished by T; bars are purple (distinct from the blue throughput and red failure rate charts); the card header shows current depth; empty state shown when no active jobs exist in the window
- Slow job detection — a configurable
slow_job_thresholdsetting (default nil = disabled) flags claimed jobs that have been running longer than the threshold; when set, the Running tab gains a "Running For" column showing each job's elapsed time, slow jobs are highlighted with an orange row background and a "slow" badge, and a "Slow Jobs" warning card appears on the dashboard linking to the Running tab
Changed
QueuesController#pause/#resumeextracted intoQueues::PausesController#create/#destroy; pause maps toPOST /queues/:name/pause, resume toDELETE /queues/:name/pauseQueues::JobsController#discard_allmerged into#destroybranching onparams[:id], matching the pattern already used inJobsController
v0.8.0
Added
- CSV export on the jobs, failed jobs, and history pages — an "Export CSV" button downloads all records matching the current filters (status, queue, search term, period) as a named
.csvfile; columns are tailored per view (enqueued_at for jobs, error details for failed jobs, duration and finished_at for history) - Dashboard quick actions — "Retry All Failed" and "Discard All Blocked" buttons appear as cards on the dashboard when the respective count is non-zero; each includes a confirm dialog and redirects back to the dashboard with a count notice; cards are hidden when everything is healthy
- Dark mode — a ☽/☀ toggle button in the header switches between light and dark themes; preference persists to
localStorageand falls back to the OSprefers-color-schemeon first visit; implemented via a[data-theme="dark"]attribute on<html>so all CSS custom properties inherit the new palette automatically; badge and flash hardcoded hex colors get explicit dark-mode overrides in a new_12_dark_mode.csspartial; powered by a new Stimulustheme_controller - Configurable settings via
SolidQueueWeb.configure—page_size(Pagy limit, default 25),dashboard_refresh_interval(ms, default 5 000),default_refresh_interval(ms, default 10 000 — applies to jobs, processes, and history pages),search_results_limit(max results per status in global search, default 25); all settings have safe defaults so zero host-app configuration is required
Changed
FailedJobsController#destroyand#discard_allconsolidated into a singledestroyaction branching onparams[:id];discard_allroute maps todestroyviaaction:optionFailedJobsController#retryand#retry_allextracted into a newRetryFailedJobsController#createaction with the same single/bulk branching patternJobsController#destroyand#discard_allconsolidated the same way, preserving the Turbo Stream response for the single-job path
v0.7.0
Added
- Queue latency detail — oldest ready job age per queue; replaces the verbose
human_latencystring withformat_durationoutput (e.g. "1h 12m"); color-coded orange above 1 hour, red above 24 hours; hovering shows the absolute UTC timestamp of the oldest waiting job; empty queues show "—" - Queue throughput columns — Done (24h) and Failed (24h) counts per queue on the Queues page; powered by two grouped COUNT queries; Done renders in green, Failed renders in red when non-zero
- Auto-refresh on the Job History page — wraps the page in a turbo-frame polled every 10 seconds, matching the jobs and processes pages; pauses when the browser tab is hidden
- Job History page (
/jobs/history) — browsable list of all finished jobs (finished_at IS NOT NULL) ordered by most-recent-first; columns show class name (links to job detail), queue (clickable queue filter), duration (formatted asXs,Xm Xs, orXh Xm), and finished timestamp; filterable by time period (1h / 24h / 7d), queue name, and class name search; paginated; "Done (1h)" and "Done (24h)" dashboard stat cards now link to the history page pre-filtered by period; "History" nav link added between Jobs and Failed - Throughput section on the dashboard — "Done (1h)" and "Done (24h)" stat cards show completed-job counts; a full-width "Throughput — Last 12 Hours" card displays a pure-CSS bar chart (12 hourly buckets, oldest left → newest right, tick labels every 3 bars) with no JavaScript or charting library; powered by a single
pluck(:finished_at)query with Ruby-side grouping for DB-agnostic compatibility; seed data updated with a realistic daily-pattern distribution so the chart shows meaningful data out of the box
Changed
- CSS split into 10 focused partial files (
_01_base.cssthrough_10_responsive.css);inline_styleshelper globs_*.cssfiles in sort order — runtime output is identical, authoring is easier
Fixed
- Auto-refresh no longer wipes checkbox selections — refresh skips its tick whenever any checkbox inside the turbo-frame is checked and resumes once selections are cleared or submitted
v0.6.0
Added
- Job selection and targeted bulk actions — checkboxes on the jobs index (ready/scheduled/blocked) and failed jobs index; a selection bar appears above the table showing the count and action buttons ("Discard Selected" for jobs, "Retry Selected" / "Discard Selected" for failed jobs); select-all checkbox in the table header; powered by a new
selectionStimulus controller that injects checked IDs into a hidden form on submit; uses nested singular resources (Jobs::SelectionsController,FailedJobs::SelectionsController) following Rails conventions - Auto-refresh for dashboard, jobs list, and processes — a
refreshStimulus controller polls the current page at a configurable interval (5 s for dashboard, 10 s for jobs/processes) and swaps the matching<turbo-frame>content in place; polling pauses when the browser tab is hidden and resumes with an immediate refresh when the tab becomes visible again - Time-based period filter (
?period=1h|24h|7d) on the jobs and failed jobs indexes — filters results by enqueued timestamp; period pills render inline with the search bar, right-justified; active period is preserved across status tab switches, search, queue filters, and bulk actions - Global job search at
/jobs/search— queries all execution models (ready, scheduled, claimed, blocked, failed) by class name substring; results grouped by status with match count and a "View all →" link; native<datalist>autocomplete pre-populated from all known job class names; auto-submits on datalist selection via thesearchStimulus controller spec/dummy/bin/rails— enablesbin/rails consoleandbin/rails serverfrom the dummy app directory during local development