fix(ui): снимать статус live при отсутствии обновлений
This commit is contained in:
1 parent
5734340db2
commit
f50a29f116
8 files changed
+103
-5
No files matched your search
+13
-1
@@ -37,7 +37,10 @@ export function useFlowLive(opts: {
|
||||
useEffect(() => {
|
||||
if (!opts.enabled) return
|
||||
const ac = new AbortController()
|
||||
let sampleTimer: ReturnType<typeof setTimeout> | undefined
|
||||
const stopTimer = () => clearTimeout(sampleTimer)
|
||||
const setError = (error: string) => {
|
||||
stopTimer()
|
||||
if (!ac.signal.aborted) setResult(previous => ({ key, sample: previous?.key === key ? previous.sample : null, receivedAt: previous?.key === key ? previous.receivedAt : null, error }))
|
||||
}
|
||||
const path = `/api/traffic/flow/live${flowQuery({
|
||||
@@ -50,6 +53,12 @@ export function useFlowLive(opts: {
|
||||
excludeOverlay: opts.excludeOverlay,
|
||||
})}`
|
||||
const url = resolveApiUrl(opts.backendUrl, path)
|
||||
// Backend ticks every 1.5–2s; tolerate several missed samples. Heartbeats do not reset this timer.
|
||||
const awaitSample = () => {
|
||||
stopTimer()
|
||||
sampleTimer = setTimeout(() => setError("Нет обновлений live более 15 секунд"), 15_000)
|
||||
}
|
||||
awaitSample()
|
||||
|
||||
let buf = ""
|
||||
|
||||
@@ -82,6 +91,7 @@ export function useFlowLive(opts: {
|
||||
if (!isValidFlowLiveSample(parsed)) {
|
||||
throw new Error("Некорректные данные live-потока")
|
||||
}
|
||||
awaitSample()
|
||||
setResult({ key, sample: parsed, receivedAt: Date.now(), error: parsed.degraded ? "Коллектор перегружен: упрощённая аналитика" : null })
|
||||
} else if (ev.event === "error" && ev.data) {
|
||||
const parsed: unknown = JSON.parse(ev.data)
|
||||
@@ -93,10 +103,12 @@ export function useFlowLive(opts: {
|
||||
if (ac.signal.aborted) return
|
||||
setError(e instanceof Error ? e.message : "Ошибка live-потока")
|
||||
ac.abort()
|
||||
} finally {
|
||||
stopTimer()
|
||||
}
|
||||
})()
|
||||
|
||||
return () => ac.abort()
|
||||
return () => { stopTimer(); ac.abort() }
|
||||
}, [opts.enabled, opts.backendUrl, opts.range, opts.serverId, opts.userId, opts.iface, opts.dedup, opts.excludeMesh, opts.excludeOverlay, key])
|
||||
|
||||
return result?.key === key ? { sample: result.sample, error: result.error, receivedAt: result.receivedAt } : { sample: null, error: null, receivedAt: null }
|
||||
|
||||
Reference in new issue
Block a user