"use client" import Link from "next/link" import {useCallback,useEffect,useRef,useState} from "react" import {Button} from "@/components/ui/button" import {DataPageCard} from "@/components/data-page-card" import {ProbesSpeedProbesDataGrid} from "@/components/data-grids/probes-speed-probes-data-grid" import {can,ensureAuthConfig} from "@/lib/auth" import {readProbeSchedule,type SpeedProbeApiRow} from "@/lib/probe-schedule-response" import type {Server} from "@/lib/data" import {requestJson} from "@/shared/api/http-client" type Snapshot={rows:SpeedProbeApiRow[]|undefined;loading:boolean;error:string|null;receivedAt:string|null} export function ProbesSpeedSchedule({base,serversForName}:{base:string;serversForName:Server[]}){ const [state,setState]=useState({rows:undefined,loading:true,error:null,receivedAt:null}) const active=useRef(false),revision=useRef(0),request=useRef(null),timer=useRef|null>(null) const refresh=useCallback(async()=>{ if(!active.current||request.current)return const id=++revision.current,controller=new AbortController();request.current=controller const current=()=>active.current&&revision.current===id&&!controller.signal.aborted setState(previous=>({...previous,loading:true,error:null})) timer.current=setTimeout(()=>{if(current()){revision.current++;controller.abort();request.current=null;setState(previous=>({...previous,loading:false,error:"Время ожидания проб скорости истекло. Повторите обновление."}))}},30000) try{ await ensureAuthConfig();if(!current())return if(!can("mm:uptime:read")){setState({rows:undefined,loading:false,error:"Нет права читать пробы скорости.",receivedAt:null});return} const rows=readProbeSchedule(await requestJson(base,"/api/uptime/speed-probes",{signal:controller.signal,cache:"no-store"})) if(current()){ if(!can("mm:uptime:read")){setState({rows:undefined,loading:false,error:"Нет права читать пробы скорости.",receivedAt:null});return} setState({rows,loading:false,error:null,receivedAt:new Date().toISOString()}) } }catch(error){if(current())setState(previous=>({...previous,loading:false,error:error instanceof Error?error.message:"Не удалось прочитать пробы скорости."}))} finally{if(revision.current===id){if(timer.current)clearTimeout(timer.current);timer.current=null;request.current=null}} },[base]) useEffect(()=>{const generation=revision;active.current=true;let pending=true;queueMicrotask(()=>{if(pending)void refresh()});return()=>{pending=false;active.current=false;generation.current++;request.current?.abort();request.current=null;if(timer.current)clearTimeout(timer.current)}},[refresh]) return

{state.loading?"Обновление проб скорости…":state.receivedAt?"Последние данные получены: "+new Date(state.receivedAt).toLocaleString("ru-RU"):"Данные проб скорости ещё не получены."}

{state.error?

{state.error}{state.rows!==undefined?" Показан последний успешный список.":""}

:null} {state.rows!==undefined?serversForName.find(s=>s.id===id)?.name??id}/>:null}

Показаны пробы скорости коллектора. Периодичность запуска задаётся в сборе данных; отдельного расписания диагностических GRE-тестов в живом режиме нет.

Настроить пробы в мониторингеОткрыть сбор данных
}