feat(telemetry): expose compute pipeline stage metrics

This commit is contained in:
DCCONSTRUCTIONS
2026-07-29 01:53:31 +03:00
parent 783aa444ac
commit 79eb4b46f7
19 changed files with 1000 additions and 24 deletions
@@ -57,6 +57,7 @@ function emptyDraft(): ComputeContourDraft {
mqtt_host: "127.0.0.1",
mqtt_port: 1883,
telemetry_poll_interval_seconds: DEFAULT_TELEMETRY_POLL_INTERVAL_SECONDS,
mqtt_publish_interval_seconds: 2,
};
}
@@ -72,6 +73,7 @@ function draftFromContour(contour: ComputeContour | null): ComputeContourDraft {
mqtt_host: contour.mqtt_host,
mqtt_port: contour.mqtt_port,
telemetry_poll_interval_seconds: contour.telemetry_poll_interval_seconds,
mqtt_publish_interval_seconds: contour.mqtt_publish_interval_seconds,
};
}
@@ -87,6 +89,9 @@ export function ComputeContourSettingsWindow({
const [telemetryPollIntervalDraft, setTelemetryPollIntervalDraft] = useState(
() => String(draftFromContour(contour).telemetry_poll_interval_seconds),
);
const [mqttPublishIntervalDraft, setMqttPublishIntervalDraft] = useState(
() => String(draftFromContour(contour).mqtt_publish_interval_seconds),
);
const [activeSection, setActiveSection] = useState<"connection" | "agent">("connection");
const [install, setInstall] = useState<ComputeContourAgentInstall | null>(null);
const [busy, setBusy] = useState(false);
@@ -97,6 +102,7 @@ export function ComputeContourSettingsWindow({
const nextDraft = draftFromContour(mode === "edit" ? contour : null);
setDraft(nextDraft);
setTelemetryPollIntervalDraft(String(nextDraft.telemetry_poll_interval_seconds));
setMqttPublishIntervalDraft(String(nextDraft.mqtt_publish_interval_seconds));
setActiveSection("connection");
setInstall(null);
setError(null);
@@ -121,6 +127,10 @@ export function ComputeContourSettingsWindow({
() => parseTelemetryPollIntervalDraft(telemetryPollIntervalDraft),
[telemetryPollIntervalDraft],
);
const mqttPublishIntervalSeconds = useMemo(
() => parseTelemetryPollIntervalDraft(mqttPublishIntervalDraft),
[mqttPublishIntervalDraft],
);
const valid = useMemo(() => (
Boolean(draft.display_name.trim())
@@ -130,7 +140,8 @@ export function ComputeContourSettingsWindow({
&& Number.isInteger(draft.mqtt_port)
&& draft.mqtt_port > 0
&& telemetryPollIntervalSeconds !== null
), [draft, telemetryPollIntervalSeconds]);
&& mqttPublishIntervalSeconds !== null
), [draft, mqttPublishIntervalSeconds, telemetryPollIntervalSeconds]);
const commitTelemetryPollInterval = () => {
const resolution = resolveTelemetryPollIntervalDraft(
@@ -149,11 +160,34 @@ export function ComputeContourSettingsWindow({
));
};
const commitMqttPublishInterval = () => {
const resolution = resolveTelemetryPollIntervalDraft(
mqttPublishIntervalDraft,
draft.mqtt_publish_interval_seconds,
);
setMqttPublishIntervalDraft(resolution.draft);
if (!resolution.accepted) return;
setDraft((current) => (
current.mqtt_publish_interval_seconds === resolution.seconds
? current
: {
...current,
mqtt_publish_interval_seconds: resolution.seconds,
}
));
};
const save = async () => {
if (!valid || busy || telemetryPollIntervalSeconds === null) return;
if (
!valid
|| busy
|| telemetryPollIntervalSeconds === null
|| mqttPublishIntervalSeconds === null
) return;
const committedDraft = {
...draft,
telemetry_poll_interval_seconds: telemetryPollIntervalSeconds,
mqtt_publish_interval_seconds: mqttPublishIntervalSeconds,
};
setBusy(true);
setError(null);
@@ -273,7 +307,7 @@ export function ComputeContourSettingsWindow({
}))}
/>
<TextField
label="Интервал MQTT"
label="Обновление интерфейса"
hint="1–60 с"
type="text"
inputMode="numeric"
@@ -296,6 +330,30 @@ export function ComputeContourSettingsWindow({
}
}}
/>
<TextField
label="Интервал MQTT агента"
hint="1–60 с · применяется конфигурацией агента"
type="text"
inputMode="numeric"
autoComplete="off"
aria-invalid={mqttPublishIntervalSeconds === null}
value={mqttPublishIntervalDraft}
onChange={(event) => setMqttPublishIntervalDraft(event.currentTarget.value)}
onBlur={commitMqttPublishInterval}
onKeyDown={(event) => {
if (event.key === "Enter") {
event.preventDefault();
event.stopPropagation();
commitMqttPublishInterval();
} else if (event.key === "Escape") {
event.preventDefault();
event.stopPropagation();
setMqttPublishIntervalDraft(
String(draft.mqtt_publish_interval_seconds),
);
}
}}
/>
{draft.telemetry_mode === "legacy-ssh" ? (
<TextField
label="SSH port"