dashboard: remove the flow page and the endpoints only it used
The flow page showed the raw broker message stream and had a compose box. This removes the page and its bundle, its link in the pages menu, and the styles only it used. The history endpoint that backfilled it and the operator-send endpoint behind the compose box had no other caller, so they go too, along with the broker query behind the history endpoint. The stream endpoint stays: the dashboard tabs still subscribe to it. The docs lose the FL0W section and the references to the two endpoints.
This commit is contained in:
parent
acf82beba3
commit
fa131b46a6
24 changed files with 62 additions and 1121 deletions
|
|
@ -1,17 +1,14 @@
|
|||
//! `/api/state` cold-load snapshot plus the dashboard's live read side:
|
||||
//! the `StateSnapshot` shape and its view builders, the
|
||||
//! `/api/dashboard/stream` SSE channel, and the `/api/dashboard/history`
|
||||
//! backfill. SPA shape + SSE channels: docs/web-ui/shape.md.
|
||||
//! `/api/dashboard/stream` SSE channel. SPA shape + SSE channels:
|
||||
//! docs/web-ui/shape.md.
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::HeaderMap,
|
||||
response::{
|
||||
IntoResponse, Response,
|
||||
sse::{Event, KeepAlive, Sse},
|
||||
},
|
||||
response::sse::{Event, KeepAlive, Sse},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio_stream::wrappers::BroadcastStream;
|
||||
|
|
@ -20,9 +17,9 @@ use utoipa::IntoParams;
|
|||
|
||||
use crate::container_view::ContainerView;
|
||||
|
||||
use super::AppState;
|
||||
use super::meta_inputs::{MetaInputView, read_meta_inputs};
|
||||
use super::tombstones::{TombstoneView, build_tombstone_views};
|
||||
use super::{AppState, error_response, scan_validated_paths};
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Serialize)]
|
||||
|
|
@ -351,105 +348,14 @@ pub(super) async fn jobq_rollup(
|
|||
axum::Json(state.coord.job_queue.state_rollup())
|
||||
}
|
||||
|
||||
/// Response body for `/api/dashboard/history`. No `ToSchema` — its
|
||||
/// `events` field wraps [`crate::dashboard_events::DashboardEvent`],
|
||||
/// which doesn't derive `ToSchema` either (a large enum with many
|
||||
/// variants; see that type's doc comment for why annotating it is
|
||||
/// out of scope here). The `responses(...)` doc below spells out the
|
||||
/// shape in prose instead of a `body = ...` reference.
|
||||
#[derive(Serialize)]
|
||||
struct DashboardHistoryBody {
|
||||
seq: u64,
|
||||
events: Vec<crate::dashboard_events::DashboardEvent>,
|
||||
}
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
path = "/api/dashboard/history",
|
||||
responses(
|
||||
(status = 200, description = "`{ seq, events }` — up to the last 200 \
|
||||
broker messages as `DashboardEvent::Sent`/`Delivered` JSON, plus \
|
||||
`seq`: the dashboard channel's high-water mark at fetch time \
|
||||
(used by clients to dedupe against buffered live SSE frames)"),
|
||||
),
|
||||
tag = "state_snapshot"
|
||||
)]
|
||||
pub(super) async fn dashboard_history(State(state): State<AppState>) -> Response {
|
||||
// Backfill source for the dashboard terminal. Returns up to ~200
|
||||
// historical broker messages (no other event kinds are persisted)
|
||||
// converted to `DashboardEvent::Sent` JSON so the client can replay
|
||||
// through the same dispatch path as live frames. Wrapped in
|
||||
// `{ seq, events }`: the seq is the dashboard channel's high-water
|
||||
// mark at fetch time. Clients use it to dedupe their buffered live
|
||||
// SSE traffic (drop anything with `seq <= history_seq`) so a frame
|
||||
// that lands between SSE-subscribe and history-fetch isn't shown
|
||||
// twice and isn't lost. Historical rows carry `seq = 0`; the
|
||||
// boundary seq is what closes the dedupe window.
|
||||
const HISTORY_LIMIT: u64 = 200;
|
||||
let seq = state.coord.current_seq();
|
||||
match state.coord.broker.recent_all(HISTORY_LIMIT) {
|
||||
Ok(mut messages) => {
|
||||
messages.reverse();
|
||||
let events: Vec<crate::dashboard_events::DashboardEvent> = messages
|
||||
.into_iter()
|
||||
.map(|m| match m {
|
||||
crate::broker::MessageEvent::Sent {
|
||||
id,
|
||||
from,
|
||||
to,
|
||||
body,
|
||||
at,
|
||||
in_reply_to,
|
||||
} => {
|
||||
let file_refs = scan_validated_paths(&body);
|
||||
crate::dashboard_events::DashboardEvent::Sent {
|
||||
seq: 0,
|
||||
id,
|
||||
from,
|
||||
to,
|
||||
body,
|
||||
at: hive_sh4re::wire_time::from_secs(at),
|
||||
in_reply_to,
|
||||
file_refs,
|
||||
}
|
||||
}
|
||||
crate::broker::MessageEvent::Delivered {
|
||||
id,
|
||||
from,
|
||||
to,
|
||||
body,
|
||||
at,
|
||||
in_reply_to,
|
||||
} => {
|
||||
let file_refs = scan_validated_paths(&body);
|
||||
crate::dashboard_events::DashboardEvent::Delivered {
|
||||
seq: 0,
|
||||
id,
|
||||
from,
|
||||
to,
|
||||
body,
|
||||
at: hive_sh4re::wire_time::from_secs(at),
|
||||
in_reply_to,
|
||||
file_refs,
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
axum::Json(DashboardHistoryBody { seq, events }).into_response()
|
||||
}
|
||||
Err(e) => error_response(&format!("dashboard/history failed: {e:#}")),
|
||||
}
|
||||
}
|
||||
|
||||
/// `/dashboard/stream` query string. Today's only field is `kinds`:
|
||||
/// a comma-separated allow-list of event-`kind` strings.
|
||||
/// Empty / absent ⇒ no filter (current behaviour, all variants
|
||||
/// forwarded). Set ⇒ only the named kinds reach the subscriber,
|
||||
/// non-matches are skipped before the JSON serialise cost.
|
||||
///
|
||||
/// Useful for narrow pages (e.g. `flow.js` only cares about `sent`
|
||||
/// / `delivered` / `container_state_changed` / `container_removed`)
|
||||
/// that want to drop the dispatch overhead on every unrelated mutation.
|
||||
/// Useful for narrow pages that only care about a few kinds and want to
|
||||
/// drop the dispatch overhead on every unrelated mutation.
|
||||
#[derive(Deserialize, Default, IntoParams)]
|
||||
pub(super) struct DashboardStreamQuery {
|
||||
/// Comma-separated event kinds to forward. Each token is
|
||||
|
|
@ -464,8 +370,7 @@ pub(super) struct DashboardStreamQuery {
|
|||
params(DashboardStreamQuery),
|
||||
responses(
|
||||
(status = 200, description = "server-sent event stream; each event's \
|
||||
`data` is a JSON-serialised `DashboardEvent` (seq-tagged; pair \
|
||||
with `/api/dashboard/history` to backfill + dedupe on connect)",
|
||||
`data` is a JSON-serialised `DashboardEvent` (seq-tagged)",
|
||||
body = String, content_type = "text/event-stream"),
|
||||
),
|
||||
tag = "state_snapshot"
|
||||
|
|
|
|||
Loading…
Reference in a new issue