fix(ui): привязать flow-аналитику к контексту запроса

This commit is contained in:
Denozordec committed 2026-09-24 01:31:43 +07:00
1 parent 94dd453b33
commit 24313340d5
5 files changed
+163 -82

No files matched your search

+12 -15
View File
@@ -32,19 +32,15 @@ export function useFlowLive(opts: {
excludeMesh?: boolean
excludeOverlay?: boolean
}): { sample: FlowAnalyticsDto | null; error: string | null } {
const [sample, setSample] = useState<FlowAnalyticsDto | null>(null)
const [error, setError] = useState<string | null>(null)
const key = JSON.stringify([opts.enabled, opts.backendUrl, opts.range, opts.serverId, opts.userId, opts.iface, opts.dedup, opts.excludeMesh, opts.excludeOverlay])
const [result, setResult] = useState<{ key: string; sample: FlowAnalyticsDto | null; error: string | null } | null>(null)
useEffect(() => {
if (!opts.enabled) {
setSample(null)
setError(null)
return
}
if (!opts.enabled) return
const ac = new AbortController()
setSample(null)
setError(null)
const setError = (error: string) => {
if (!ac.signal.aborted) setResult(previous => ({ key, sample: previous?.key === key ? previous.sample : null, error }))
}
const path = `/api/traffic/flow/live${flowQuery({
range: opts.range,
serverId: opts.serverId,
@@ -65,6 +61,7 @@ export function useFlowLive(opts: {
signal: ac.signal,
credentials: "include",
})
if (ac.signal.aborted) return
if (!res.ok || !res.body) {
setError(`live HTTP ${res.status}`)
return
@@ -73,7 +70,8 @@ export function useFlowLive(opts: {
const decoder = new TextDecoder()
while (!ac.signal.aborted) {
const { done, value } = await reader.read()
if (done) break
if (ac.signal.aborted) return
if (done) { setError("Поток live завершён"); break }
buf += decoder.decode(value, { stream: true })
const parts = buf.split("\n\n")
buf = parts.pop() ?? ""
@@ -86,8 +84,7 @@ export function useFlowLive(opts: {
setError("live sample пустой")
continue
}
setSample(parsed)
setError(parsed.degraded ? "Коллектор перегружен: упрощённая аналитика" : null)
setResult({ key, sample: parsed, error: parsed.degraded ? "Коллектор перегружен: упрощённая аналитика" : null })
} else if (ev.event === "error" && ev.data) {
const parsed = JSON.parse(ev.data) as { error?: string }
setError(parsed.error ?? "live error")
@@ -101,7 +98,7 @@ export function useFlowLive(opts: {
})()
return () => ac.abort()
}, [opts.enabled, opts.backendUrl, opts.range, opts.serverId, opts.userId, opts.iface, opts.dedup, opts.excludeMesh, opts.excludeOverlay])
}, [opts.enabled, opts.backendUrl, opts.range, opts.serverId, opts.userId, opts.iface, opts.dedup, opts.excludeMesh, opts.excludeOverlay, key])
return { sample, error }
return result?.key === key ? { sample: result.sample, error: result.error } : { sample: null, error: null }
}