Skip to content

RQ

Requires RQ 1.10.1+ and <3, Python 3.11+. See the compatibility matrix for the full pin string.

Terminal window
pip install z4j-rq

RQ does not expose a worker middleware system. z4j wraps the class that owns Worker.execute_job, the parent-side execution boundary, and also provides optional per-job callback functions.

Hook z4j event
Before Worker.execute_job task.started
Finished job status after Worker.execute_job task.succeeded
Failed or stopped status after Worker.execute_job task.failed
Explicit per-job stopped callback task.revoked
Verb How
submit enqueue the import-path task name on the selected queue
retry requeue a failed job by reference; complete operator-supplied replacements use a new enqueue
cancel send_stop_job_command if running; job.cancel() if queued, deferred, or scheduled
purge_queue guarded queue.empty()
bulk_retry retry explicit project-owned task IDs only, capped at 10,000
requeue_dead_letter requeue from RQ's FailedJobRegistry

RQ uses many queues per app. The adapter discovers queues through Queue.all(connection) when it builds queue and task snapshots. Each queue appears separately in the dashboard with its own counts.

rq-worker-pool works fine - each worker in the pool registers as its own agent. Use agent_name with $PID to distinguish.

For POSIX fork workers, z4j-rq provides a corrected worker using RQ's supported worker-class option:

Terminal window
rq worker --worker-class z4j_rq.worker.Worker default

Keep your application's queue names, Redis options, settings module and z4j startup integration. Applications that construct workers in Python can use from z4j_rq.worker import Worker with their existing constructor arguments.

The investigation identified the source of the earlier Linux parent-memory growth: stock RQ assigns every new RQ_JOB_ID to the long-lived parent's environment as well as the child's. glibc retains distinct environment values. The corrected worker makes those assignments only in the short-lived child, where the job still receives its worker ID and job ID. It inherits RQ's job execution, monitoring, timeouts, callbacks, retries and shutdown, preserving RQ 1.x session isolation and RQ 2.x process-group isolation.

This class must be selected explicitly. Installing z4j-rq does not change stock/custom workers, and this repair does not replace SimpleWorker, SpawnWorker or Windows worker implementations. Custom classes that override the fork boundary need their own integration review.

For an affected stock fork worker that has not switched to the corrected class, the previously verified fallback remains rq worker --max-jobs 50000 default under a process manager that restarts successful exits (Restart=always for systemd or autorestart=true for Supervisor). Allow current jobs to finish during shutdown. Keep normal process supervision, memory monitoring and job idempotency with either worker; fixing this allocation does not prevent memory growth caused by application code or establish unlimited worker lifetimes.

  • Failed queue - RQ moves failures to a FailedJobRegistry. z4j uses that registry for retry and dead-letter requeue actions; lifecycle visibility comes from the worker hook.
  • Scheduler actions - the rq-scheduler companion supports list, trigger, destructive disable, and delete. It does not support create, update, or enable; re-enable by registering the job again from application code.
  • Dependencies - job.depends_on chains show in the dashboard as "waiting on".

Pass the application's queue, scheduler, or another object that exposes its Redis connection to the adapter:

from z4j_rq import RqEngineAdapter
adapter = RqEngineAdapter(rq_app=queue)

See scheduler: rq-scheduler.