Background Jobs and the Queue
Most of the work REQQA does on your behalf is slow. Running the DeFOSPAM analysers against a requirement means one or more calls to a large language model; analysing every requirement in an application means dozens of those calls; generating stories, grouping an import, and analysing a mission all take seconds to minutes each. If REQQA tried to do that work inside the web request that triggered it, your browser would sit waiting — and time out long before the work finished.
So REQQA does not do this work in the request. Instead it queues the work as a background job, returns control to you immediately, and lets a pool of worker processes pick the job up and run it. You watch progress on the Job Queue page rather than staring at a frozen browser tab.
This page explains what that machinery is, what gets queued, and how to monitor it. You do not need to understand any of it to use REQQA — but knowing where the work happens makes the occasional wait, and the occasional failure, far easier to reason about.
Why background jobs exist
A single requirement analysis can issue a separate AI call for each analyser you've selected. The Analyse All action on the requirements list fans that out across every selected requirement at once. A mission generation run reads your mission and produces a whole hierarchy of requirements. None of these can complete in the lifetime of an HTTP request.
By moving the work onto a queue, REQQA gets three things:
- Responsiveness — the page that started the job comes back at once with a "queued" message, not a spinner.
- Throughput — several jobs run in parallel across multiple workers, so analysing 30 requirements does not mean waiting for them one after another.
- Resilience — a job that fails (an AI timeout, a malformed response) fails on its own without taking your browser session, or the other jobs, down with it.
Redis Queue and the workers
REQQA's background processing is built on Redis Queue (RQ). There are two halves:
- The queue. When you trigger a job, the controller writes a tracking row to the
database, then places a job on a Redis-backed queue named
defospam. The controller returns immediately. The job itself is just a reference to a runner function (for examplemodules.analysisJobRunner.run_requirement_analysis) plus its arguments. - The workers. A pool of long-running worker processes watches that queue. When a job appears, a free worker claims it, imports the runner fresh, executes it, updates the tracking row as it goes, and then waits for the next job. REQQA currently runs five workers, so up to five jobs run at the same time; anything beyond that waits in the queue until a worker frees up.
RQ workers and the web application are separate processes. That is by design — it's what lets analysis keep running even while you navigate away. It also means workers import your code freshly for each job, so a job always runs against the current logic.
RQ versus the py4web scheduler
py4web ships with its own built-in task scheduler, and REQQA used it in the past. That scheduler has since been retired: all of REQQA's asynchronous work now goes through RQ. You will not find a separate "scheduled tasks" surface in the application — the Job Queue page is the single place where background work is visible.
What gets queued
Not everything is a background job. Quick operations — saving a requirement, editing the mission, toggling a flag — happen inline in the request and are done before the page reloads. What goes on the queue is the expensive, AI-driven work:
| Job type | What triggers it | What it does |
|---|---|---|
| Analysis | Analysing a single requirement, or Analyse All on a selection | Runs the chosen DeFOSPAM analyser steps (for example R-D, R-F) against each requirement and records the issues found |
| Reqs Gen | Generating requirements from a mission | Reads the mission and produces a requirements hierarchy beneath it |
| Story Gen | Generating stories for a requirement | Produces user stories / Gherkin from a requirement |
| Synthesis | Synthesising or cleaning up after analysis | Consolidates and reworks requirements across a group |
| CSV Import (grouped / consolidated) | Importing requirements with AI grouping or consolidation | Imports the rows, then groups or consolidates them with AI |
| Training Gen | Generating demonstration / training data | Produces sample requirements for an organisation |
For requirement analysis, the analyser steps you select map directly onto the work the job
does. A requirement might be queued with a step code of R-D,R-F — that single job runs
the data/definition analyser and the feature analyser in turn. Analyse All simply
creates one such job per selected requirement and enqueues them all at once, which is why a
bulk run can put many jobs on the queue in one click.
When you queue a fresh analysis for a requirement that has already been analysed, REQQA marks the previous run — and its still-open issues — as Superseded before the new job runs. The Job Queue's history reflects this: superseded runs drop out of the active list.
Monitoring on the Job Queue page
The Job Queue page is how you watch background work — and it is the right way to do it. Do not try to infer progress from the page that launched the job, and do not guess. The Job Queue shows you exactly what is queued, what is running, and what recently finished or failed, for your current application.
The page is organised around two ideas:
- Active jobs — anything queued (waiting for a free worker) or running (a worker is on it now).
- Recent jobs — the last several runs that have reached a terminal state: finished, Partial (some steps succeeded, some did not), failed, or Superseded.
For each row you can see the job type, its status, how many analyser steps it covers, the issue counts it produced, and — for analyses — a live progress percentage and a "current step" label as the worker moves through the steps. Each row links through to the relevant results: an analysis links to its issues, a generation job to its output, a synthesis run to its results.
After you trigger an analysis or a generation, the launching page tells you the job is queued and invites you to refresh. For anything that takes more than a moment, open the Job Queue page instead — it is purpose-built to show progress and will tell you the moment a job finishes or fails, with a link straight to the result.
Progress tracking
Analysis jobs carry their own progress state, which the worker updates as it runs. The tracking row records the total number of steps, how many are complete, a progress percentage, and the name of the step currently in flight. That is what the Job Queue renders as a progress indicator — it is real progress reported by the worker, not an estimate.
When a job finishes cleanly its status becomes finished. If some steps succeeded but others failed, it ends as Partial — worth opening, because the issues that were found are still valid. A failed job produced no usable result; the most common causes are an AI timeout or an unparseable AI response, and re-running the job is usually the right next step.
What to do when a job fails
A failed job is contained — it does not affect your other jobs or your data. If you see a failed or Partial row:
- Open it from the Job Queue to see what, if anything, was produced.
- For a single requirement, simply analyse it again — a transient AI error usually clears on a retry.
- For a bulk run, re-select the requirements that did not complete and run Analyse All again; REQQA supersedes the earlier attempt automatically.
If failures persist across many jobs, that points at something shared — most often the organisation's AI configuration (a missing or invalid API key, or a model the account cannot reach) rather than any one requirement.
Related
- The Analysis Engine — what the queued analysis jobs actually do, and what the analyser steps mean.
- How to analyse a requirement — the task that puts an analysis job on the queue.
- Synthesis and Cleanup — the synthesis jobs you'll see in the queue after analysis.
- How to import requirements — the grouped and consolidated import modes run as background jobs.