feat(system): configure telemetry polling per contour

This commit is contained in:
DCCONSTRUCTIONS
2026-07-28 01:24:05 +03:00
parent 4a65b52f6d
commit 2ffbb51a7e
8 changed files with 68 additions and 23 deletions
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from "react";
import {
Button,
FeatureSettingsWindow,
FieldFrame,
Icon,
Select,
SettingsCard,
@@ -50,6 +51,7 @@ function emptyDraft(): ComputeContourDraft {
ssh_port: 22,
mqtt_host: "127.0.0.1",
mqtt_port: 1883,
telemetry_poll_interval_seconds: 3,
};
}
@@ -64,6 +66,7 @@ function draftFromContour(contour: ComputeContour | null): ComputeContourDraft {
ssh_port: contour.ssh_port,
mqtt_host: contour.mqtt_host,
mqtt_port: contour.mqtt_port,
telemetry_poll_interval_seconds: contour.telemetry_poll_interval_seconds,
};
}
@@ -111,6 +114,9 @@ export function ComputeContourSettingsWindow({
&& draft.ssh_port > 0
&& Number.isInteger(draft.mqtt_port)
&& draft.mqtt_port > 0
&& Number.isInteger(draft.telemetry_poll_interval_seconds)
&& draft.telemetry_poll_interval_seconds >= 1
&& draft.telemetry_poll_interval_seconds <= 60
), [draft]);
const save = async () => {
@@ -194,14 +200,16 @@ export function ComputeContourSettingsWindow({
expected_node_id: event.currentTarget.value,
}))}
/>
<Select
label="Платформа"
value={draft.platform}
options={platformOptions}
variant="split"
menuWidth="anchor"
onChange={(platform) => setDraft((current) => ({ ...current, platform }))}
/>
<FieldFrame label="Операционная система">
<Select
label="Операционная система"
value={draft.platform}
options={platformOptions}
variant="split"
menuWidth="anchor"
onChange={(platform) => setDraft((current) => ({ ...current, platform }))}
/>
</FieldFrame>
<TextField
label="Адрес узла"
hint="IP или hostname в текущей LAN"
@@ -230,6 +238,18 @@ export function ComputeContourSettingsWindow({
mqtt_port: Number(event.currentTarget.value),
}))}
/>
<TextField
label="Интервал MQTT"
hint="160 с"
type="number"
min={1}
max={60}
value={String(draft.telemetry_poll_interval_seconds)}
onChange={(event) => setDraft((current) => ({
...current,
telemetry_poll_interval_seconds: Number(event.currentTarget.value),
}))}
/>
{draft.telemetry_mode === "legacy-ssh" ? (
<TextField
label="SSH port"
@@ -13,6 +13,7 @@ export interface ComputeContour {
ssh_port: number;
mqtt_host: string;
mqtt_port: number;
telemetry_poll_interval_seconds: number;
revision: number;
updated_at_utc: string | null;
}
@@ -31,6 +32,7 @@ export interface ComputeContourDraft {
ssh_port: number;
mqtt_host: string;
mqtt_port: number;
telemetry_poll_interval_seconds: number;
}
export interface ComputeContourAgentInstall {
@@ -96,6 +98,7 @@ export async function createComputeContour(
ssh_port: draft.ssh_port,
mqtt_host: draft.mqtt_host,
mqtt_port: draft.mqtt_port,
telemetry_poll_interval_seconds: draft.telemetry_poll_interval_seconds,
}),
signal,
});
@@ -5,7 +5,7 @@ import {
type WorkerTelemetry,
} from "./workerTelemetry";
export const WORKER_TELEMETRY_POLL_MILLISECONDS = 3_000;
export const DEFAULT_WORKER_TELEMETRY_POLL_MILLISECONDS = 3_000;
export interface WorkerTelemetryState {
telemetry: WorkerTelemetry | null;
@@ -15,7 +15,7 @@ export interface WorkerTelemetryState {
}
export function useWorkerTelemetry(
pollMilliseconds = WORKER_TELEMETRY_POLL_MILLISECONDS,
pollMilliseconds = DEFAULT_WORKER_TELEMETRY_POLL_MILLISECONDS,
enabled = true,
): WorkerTelemetryState {
const [telemetry, setTelemetry] = useState<WorkerTelemetry | null>(null);
@@ -16,7 +16,6 @@ import {
import { useComputeContours } from "../../core/system/ComputeContourContext";
import {
useWorkerTelemetry,
WORKER_TELEMETRY_POLL_MILLISECONDS,
} from "../../core/system/useWorkerTelemetry";
function pipelineStateLabel(state: string): string {
@@ -30,8 +29,8 @@ export function ComputeModulesWorkspace() {
const legacyDiagnostic = selectedContour?.contour_id === "worker-006"
&& selectedContour.telemetry_mode === "legacy-ssh";
const supportsLiveTelemetry = selectedContour?.contour_id === "worker-006";
const { telemetry, loading, error, refresh } = useWorkerTelemetry(
WORKER_TELEMETRY_POLL_MILLISECONDS,
const { telemetry, error, refresh } = useWorkerTelemetry(
(selectedContour?.telemetry_poll_interval_seconds ?? 3) * 1_000,
supportsLiveTelemetry,
);
const node = telemetry?.node ?? null;
@@ -67,11 +66,11 @@ export function ComputeModulesWorkspace() {
<Button
size="compact"
variant="secondary"
disabled={loading}
disabled={!supportsLiveTelemetry}
onClick={refresh}
icon={<Icon name="refresh" size={14} />}
>
{loading ? "Читаем" : "Обновить"}
Обновить
</Button>
</div>
</section>
@@ -15,7 +15,6 @@ import {
import { useComputeContours } from "../../core/system/ComputeContourContext";
import {
useWorkerTelemetry,
WORKER_TELEMETRY_POLL_MILLISECONDS,
} from "../../core/system/useWorkerTelemetry";
export function NetworkWorkspace() {
@@ -23,8 +22,8 @@ export function NetworkWorkspace() {
const legacyDiagnostic = selectedContour?.contour_id === "worker-006"
&& selectedContour.telemetry_mode === "legacy-ssh";
const supportsLiveTelemetry = selectedContour?.contour_id === "worker-006";
const { telemetry, loading, error, refresh } = useWorkerTelemetry(
WORKER_TELEMETRY_POLL_MILLISECONDS,
const { telemetry, error, refresh } = useWorkerTelemetry(
(selectedContour?.telemetry_poll_interval_seconds ?? 3) * 1_000,
supportsLiveTelemetry,
);
const aggregate = telemetry?.network.aggregate ?? null;
@@ -54,11 +53,11 @@ export function NetworkWorkspace() {
<Button
size="compact"
variant="secondary"
disabled={loading || !supportsLiveTelemetry}
disabled={!supportsLiveTelemetry}
onClick={refresh}
icon={<Icon name="refresh" size={14} />}
>
{loading ? "Читаем" : "Обновить"}
Обновить
</Button>
</div>
</section>