Skip to main content

Dispatch queue

The /envois/file screen shows what is waiting to be posted. It is the other end of time compared with Dispatches, which shows what has left.

The two read two different sources, and that is the whole reason this page exists: a history row is born the moment the sender posts. A trial launched in chronological cadence for tomorrow therefore leaves nothing in the database before its first due date — and a thousand perfectly ordered batches then read as a dispatch that never happened.

You reach it from the Debug section of the navigation bar — which gathers the observation screens, as opposed to those configuring the product — from the “batches in queue” line of the dispatches screen, and from the dashboard's “Dispatch queue” card.

Four states, and not a fifth​

StateMeaning
DelayedScheduled for later — chronological cadence and live replay
WaitingRipe, they leave as soon as a sender is free
In flightCurrently being POSTed to the intake
FailedDefinitively refused, after five attempts or on an error that is not retried

Completed batches do not appear here, and that is deliberate: they left a history row, which the dispatches screen holds from the database with its outcome, its duration and its messages kept for 24 h. Reading them back here from Redis — which only keeps a hundred, for one hour — would make two screens contradict each other about the same dispatch.

A batch in flight is never purgeable: its HTTP request has already left, and removing it from the queue would not cancel it. Offering that would be a button that lies.

What the sort orders, and what it does not​

The sort bears on the natural order of the state being looked at — the due date for delayed ones, the rank for waiting ones, the instant of failure for failures — and reverses on a click on the header.

There is no sorting by destination, by technology or by message count, and no filter by source, bench, community or technology. The reason is the same in both cases: a batch carries its already-rendered messages, and nothing in the queue lets its metadata be read without its payload. Filtering or sorting on anything else would require loading the whole queue on every page render — tens of megabytes for twenty-five rows.

Every row names its source — the same coloured badge as on Dispatches, so a batch does not change colour when it leaves the queue: Normal flow, Threat scenario, Test bench or Manual dispatch, followed by its community, scenario or bench — and its technology: it is the global filter that is missing, not the information. And the purge, for its part, does accept the filter — it is a deliberate, confirmed gesture, not a page render.

Unfolding a batch​

Each row unfolds onto what the batch is about to post — in the past tense for a failed batch, which has already tried. That is what was missing most: until now, a message could only be read back after it had been sent.

The cap is the same as the one for past dispatches — one hundred messages — and the panel announces the total: “The first 100 messages of 1,000”. Nothing is truncated silently.

The batch's record names its identifier, its due date, its source, and where its intake key will be read from — never the key. Saying it is better than omitting it: “read from the bench at send time” or “read from the community at send time” explains why a delayed batch can fail hours later on a key erased in the meantime.

The unfolding works without JavaScript: the control is a link putting the open row in the URL (?ouvert=…), and the page comes back with the panel rendered. The screen therefore stays shareable.

Removing​

Four gestures, from the narrowest to the broadest:

  • one row or a selection — the table's checkboxes, then “Remove the selection”;
  • a whole state — “Empty the delayed ones”, in two steps;
  • the whole queue — delayed, waiting and failed; batches in flight are not affected, and the button says so;
  • the batches of one bench — from the bench's page, “Annuler les envois programmés”.

That last one and the per-state purge are the same gesture, filtered: a second implementation would end up removing something other than the first, and two buttons would announce two counts for the same work.

The report carries what was actually removed, detailed by state — a total alone would not say whether the failures were taken with it. It may be lower than what was asked for, and that is not an error: two tabs open on the same queue, and one purges what the other was still offering.

Confirming a mass purge goes through the URL (?supprimer=…) rather than through a dialog box: confirm() does not exist without JavaScript, and the no-JS path is one of the project's guarantees.

Pausing​

“Pause the queue” stops the pickup: no sender takes a batch any more. Nothing is lost or moved — batches stay where they are, the counters stay accurate, and what had already left completes its round trip.

The screen announces it in a banner, and it must: a paused queue that did not say so would read as an outage — batches pile up, nothing leaves, and the dispatches screen stays silent.

Replaying a failure​

A failed batch is replayed from its panel. It goes back to waiting, attempts reset to zero: that is the gesture missing when the intake was unavailable and is available again.

Real time​

The page updates itself on every completed dispatch — precisely the moment the queue changes, since a batch leaves it. The mechanism is the dispatches screen's, and it is the same stream: an announcement serves as a signal to re-read the data, which stays read from Redis. A lost announcement therefore never leaves the screen in a false state.