Skip to main content

Dispatches

The /envois screen shows everything SekoiaCraft has posted to an intake, whatever its origin. It is the global counterpart of the “Latest dispatches of this event type” panel carried by the Preview tab: there you look at one event type, here you look at the instance.

It holds the “history” part of the supervision screen planned in the roadmap; the pending jobs are on Dispatch queue, and the generation metrics will come with the steps that produce them.

What the page says​

Four summary tiles, computed on the whole filtered set and not on the displayed page — a page of 25 rows would say nothing about the success rate of the thousands of others:

TileMeaning
DispatchesTotal number of dispatches in the selection
Success rateShare of successful dispatches, and their count
FailedNumber of definitively refused dispatches
Average durationAverage of the round trips to the intake

A curve of dispatches per hour over the last 24 h, stacked by outcome. Hours with no dispatch appear there at zero: a curve skipping them would pass a quiet hour off as a busy one. Hovering a column details its content.

A table of dispatches, each with its timestamp, its outcome, its source, its technology, its destination, the HTTP status obtained, the duration and the number of attempts. Failed dispatches carry the message returned by the intake. Each row unfolds onto the messages sent (see below).

The source and the technology​

The Source column says what produced the batch, with a coloured badge — the label is always written next to the colour:

BadgeWhat produced the batchFollowed by
Normal flowThe simulated day of a communitythe community
Threat scenarioA scenario launched on a community (see Attacker background noise)the scenario · community
Test benchA test bench trialthe bench
Manual dispatchThe “Send” button of an event type's Preview tab—

The name leads to the community's Today tab, its Threats tab for a scenario, or the bench.

The Technology column names the generator, and the event type when the dispatch carries only one — an editor dispatch; the link leads straight to its editor. A bench, community or scenario batch mixes several event types of one technology, and names the technology alone.

Both survive what produced them: the history is a record. A dispatch whose event type and technology have since been deleted shows “Origin deleted”; a community or a bench deleted since shows “Community deleted” or “Bench deleted” — the badge stays, because the nature of the source is written on the row when the batch leaves. A scenario batch keeps the name of its community, copied onto the launch record.

Seeing what left​

Each row unfolds onto the messages actually posted, in the order they were sent. It is the counterpart of the rest of the table: the columns say that a dispatch left and how it was received, the unfolding says what.

A failed dispatch keeps its messages, and that is where they are most useful: they say what was attempted, hence why the intake rejected it.

The cap is a quantified refusal. A batch can carry up to a thousand messages; a hundred are kept, and the panel says so — “The first 100 messages of 1,000”. The dispatch count on the row stays exact: nothing is truncated silently.

The depth is one day, and it bears on the content, not on the row. Past 24 h, the panel says the messages are no longer kept — the dispatch itself stays in the record, with its outcome, its origin and its duration. It is the same rule that makes a row survive the deletion of its event type.

The threshold is applied on read: a message older than 24 h is refused even if it is still physically in the database. A sweeper reclaims the space in the background, but it keeps nothing — if it stopped, nothing would leak for all that. The guarantee does not depend on its good health.

What is kept are the messages, never the envelope carrying them to the intake. The intake key enters neither the database nor a response.

A dispatch predating this feature shows “No message was kept for this dispatch”: that is honest, not a defect.

The unfolding works without JavaScript: the control is a link, it puts the open row in the URL (?ouvert=…) and the page comes back with the panel rendered. The screen therefore stays shareable — a URL says what is open. With JavaScript, several rows open at once without reloading, and an open row stays open when a new dispatch arrives.

What is still waiting​

A scheduled batch only enters the list when it leaves: the row is opened by the sender service when it posts, not when the batch is queued. A trial launched in chronological cadence or in live replay (see Test benches) may therefore leave nothing here for hours.

A line above the list then says how many batches are waiting their turn, and when the first and the last due dates fall. It is deliberately outside the summary tiles: those measure what has left, and counting a scheduled batch among them would distort the page's success rate. The count bears on the whole queue, across all benches — a trial's own result gives the figures for that trial.

It carries the “Manage the queue” link, and carries it even at zero: hiding the line when nothing is waiting would remove the only way in at the precise moment you come to check that the queue is indeed empty.

What is waiting can be seen, unfolded and removed from Dispatch queue — row by row, by selection, by state or in full; and the queue can be paused there. The per-bench shortcut stays available: a bench's “Annuler les envois programmés” button empties its still-delayed batches, and says how many.

Filtering​

The status, the generator, the source and the community restrict the list, the summary and the curve together. The community filter keeps its normal flow and its threat scenarios alike — combine it with the source to keep only one of them; in a pool, it isolates a team.

The filters live in the URL (?status=, ?generatorId=, ?kind=, ?community=): the page is shareable, going back works, and the form stays usable without JavaScript. A bench's “Suivre les envois” link arrives with ?trial=, which has no field of its own but is kept when you add another filter.

Real time​

The page updates itself on every completed dispatch, without reloading.

The mechanism is deliberately modest: api-sender announces every definitive outcome on a Redis channel, api-activity turns it into an SSE stream, and the page uses it as a signal to re-read its data. Nothing displayed comes from the stream — the truth stays in the database. A lost announcement therefore never leaves the screen in a false state, and the page refreshes on connection as well as on every reconnection.

Intermediate attempts are not announced: a dispatch that will succeed on the next try would make the screen flicker for nothing.