Add a job-queue health check so stalled background jobs can't go unnoticed again
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 72/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Área
- backend, observability
Línea de trabajo
Empieza en app/controllers/health_controller.rb, junto a la acción health existente, y añade la acción jobs; la ruta va bajo resources :health en config/routes.rb. Cuenta solo las filas de Delayed::Job vencidas y no fallidas (run_at <= now, failed_at nil) usando dos consultas agregadas, y devuelve 503 cuando el trabajo vencido más antiguo supere el umbral de ENV (por defecto 3600). Está terminado cuando spec/requests/health_spec.rb cubra 200 vacío, 200 reciente, 503 obsoleto y un cuerpo sin datos del manejador ni de los argumentos.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Problem
From early 2022 until 2026-11-01, production background jobs (delayed_job) never ran: no worker dyno was on and nothing in Heroku Scheduler processed the queue. About 8,000 jobs piled up, mostly emails: followup notifications, supervisor reimbursement requests, and completed-reimbursement notices. Nobody noticed for 4.5 years, because nothing checks that jobs are actually being processed.
A Scheduler entry now runs rake jobs:workoff every 10 minutes. If it stops (removed by mistake, failing on boot, a rake-only bug like #7283), we'd be blind again.
Proposal
Add a cheap queue-health signal that an uptime monitor can poll.
- New endpoint, e.g.
GET /health/jobs.json, next to the existing/health(app/controllers/health_controller.rb, route inconfig/routes.rbunderresources :health). It returns only aggregate numbers, never job payloads (handlers contain record IDs and arguments):{"queued": 3, "oldest_queued_age_seconds": 412, "failing": 0}queued:Delayed::Job.where(failed_at: nil).countoldest_queued_age_seconds: age of the oldest job that is due to run (run_at <= now, not failed), ornullfailing: jobs withlast_errorset, orattempts > 0
- Respond 503 when the oldest due job is older than a threshold (e.g. 1 hour; configurable via ENV, default 3600), so a simple HTTP uptime check can alert on it. Otherwise 200.
- Request spec in
spec/requests/health_spec.rb: 200 with an empty queue, 200 with a fresh job, 503 with a job older than the threshold, and no handler or argument data in the response body. - Keep it cheap: two indexed aggregate queries, no loading of job rows.
- Document the endpoint in the wiki deploy checklist / README so a maintainer can point an uptime monitor at it. A maintainer will set up the actual monitor.
Notes
- Jobs with a future
run_at(retry backoff) shouldn't count as "stuck". Only count jobs that are due. - Don't require auth for the JSON, since it exposes only counts. If you'd rather gate it, follow the token pattern used by
old_objectsin the same controller.
Difficulty: beginner–intermediate. One controller action, one route, one request spec.
- Lenguaje dominante
- Ruby
- Estrellas
- 382
- Forks
- 547
- Merge medio
- 2 d 22 h
- PR fusionados (30 d)
- 46
Preparar el entorno
Inicia el contenedor de desarrollo del proyecto en tu navegador, con tu propia cuenta de GitHub.
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de rubyforgood/casa
-
Remove leftover Cloud66 custom_web process from ProcfilePosiblemente ocupada @ShahadatTest la tomó hoy. AbiertoDifficulty: Easy Good First Issue
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
rubyforgood/casa#7330 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
dependencies Difficulty: Easy Good First Issue
Dificultad 1/5 Menos de una hora Aptitud para principiantes 82/100
rubyforgood/casa#7325 ·
Los mantenedores suelen responder en 1 día
-
Difficulty: Easy Good First Issue Help Wanted javascript
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
rubyforgood/casa#7311 ·
Los mantenedores suelen responder en 1 día
-
Difficulty: Easy Good First Issue Help Wanted javascript
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
rubyforgood/casa#7310 ·
Los mantenedores suelen responder en 1 día
-
Difficulty: Easy Good First Issue Help Wanted javascript
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
rubyforgood/casa#7309 ·
Los mantenedores suelen responder en 1 día
Todos los issues de rubyforgood/casa
Issues similares
-
intercepted.rb crashes on an optional positional argument when the method also takes keywordsAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
yegor256/intercepted#128 ·
-
documentation good first issue
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
ysb3996-blip/oops#51 ·
Los mantenedores suelen responder en 1 día
-
good first issue
Dificultad 1/5 Menos de una hora Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
area:core-lib P2 size:S
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
Los mantenedores suelen responder en 1 día
-
bug needs-triaging
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
SeleniumHQ/seleniumhq.github.io#2952 · 1 comentario ·
Los mantenedores suelen responder en 1 día