feat(Mikrotik): add ping endpoint and implement prefetching of ping data for gateways in EasySwitchManager
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 3m18s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 3m18s
This commit is contained in:
@@ -47,6 +47,8 @@ function EasySwitchManager() {
|
||||
const [hasChanges, setHasChanges] = useState(false);
|
||||
const [expandedServers, setExpandedServers] = useState(new Set()); // Развернутые серверы
|
||||
const [groupByTags, setGroupByTags] = useState(true); // Группировка по тегам
|
||||
// Пинги по шлюзам: ключ `${routerId}:${gatewayIp}` → avg RTT в мс
|
||||
const [pingMap, setPingMap] = useState({});
|
||||
|
||||
useEffect(() => {
|
||||
const initData = async () => {
|
||||
@@ -146,6 +148,8 @@ function EasySwitchManager() {
|
||||
// Фильтруем серверы, у которых есть gateways
|
||||
const serversWithGateways = serversWithData.filter(s => s.gateways.length > 0);
|
||||
setServers(serversWithGateways);
|
||||
// Предзагружаем пинги для всех комбинаций server+gateway
|
||||
prefetchPings(serversWithGateways, inventory);
|
||||
|
||||
// Автоматически разворачиваем первый сервер
|
||||
if (serversWithGateways.length > 0 && expandedServers.size === 0) {
|
||||
@@ -176,6 +180,67 @@ function EasySwitchManager() {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Загрузить реальные пинги для комбинаций (сервер, gateway).
|
||||
* Пингуем хост www.gstatic.com через соответствующий MikroTik jumphost.
|
||||
*/
|
||||
const prefetchPings = async (serversList, inventory) => {
|
||||
try {
|
||||
const tasks = [];
|
||||
const seen = new Set();
|
||||
|
||||
serversList.forEach((server) => {
|
||||
const inv = inventory.find(srv =>
|
||||
String(srv.dns || '').trim() === server.name ||
|
||||
String(srv.hostName || '').trim() === server.name ||
|
||||
String(srv.ip || '').trim() === server.name
|
||||
);
|
||||
const routerId = inv?.id || inv?.dns || inv?.ip;
|
||||
if (!routerId) return;
|
||||
|
||||
(server.gateways || []).forEach((gw) => {
|
||||
const ip = gw.ip || '';
|
||||
if (!ip) return;
|
||||
const key = `${routerId}:${ip}`;
|
||||
if (seen.has(key) || pingMap[key] !== undefined) return;
|
||||
seen.add(key);
|
||||
tasks.push({ routerId, ip, key });
|
||||
});
|
||||
});
|
||||
|
||||
if (tasks.length === 0) return;
|
||||
|
||||
const results = await Promise.all(
|
||||
tasks.map(async ({ routerId, ip, key }) => {
|
||||
try {
|
||||
const { data } = await api.post('/mikrotik/ping', {
|
||||
serverId: routerId,
|
||||
gatewayIp: ip,
|
||||
target: 'www.gstatic.com',
|
||||
count: 5,
|
||||
});
|
||||
return { key, value: typeof data?.avgMs === 'number' ? Math.round(data.avgMs) : null };
|
||||
} catch (e) {
|
||||
console.warn('Failed to fetch ping for', routerId, ip, e?.message || e);
|
||||
return { key, value: null };
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
if (results.length > 0) {
|
||||
setPingMap(prev => {
|
||||
const next = { ...prev };
|
||||
results.forEach(r => {
|
||||
next[r.key] = r.value;
|
||||
});
|
||||
return next;
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('prefetchPings error:', e?.message || e);
|
||||
}
|
||||
};
|
||||
|
||||
const handleGatewaySelect = (serverId, community, gateway) => {
|
||||
const key = `${serverId}:${community}`;
|
||||
setActiveGateways(prev => {
|
||||
@@ -711,7 +776,12 @@ function EasySwitchManager() {
|
||||
{server.gateways.map((gw, idx) => {
|
||||
const isActive = activeGw === gw.name;
|
||||
const isFastest = idx === 0;
|
||||
const ping = 20 + idx * 10 + Math.floor(Math.random() * 15);
|
||||
const pingKey = (() => {
|
||||
const inv = getServerMetadata(server.name);
|
||||
const routerId = inv?.id || inv?.dns || inv?.ip;
|
||||
return routerId && gw.ip ? `${routerId}:${gw.ip}` : null;
|
||||
})();
|
||||
const ping = pingKey && pingMap[pingKey] !== undefined ? pingMap[pingKey] : null;
|
||||
|
||||
return (
|
||||
<div key={gw.name} className="col-12 col-sm-4">
|
||||
@@ -785,7 +855,7 @@ function EasySwitchManager() {
|
||||
|
||||
{/* Метрика (пинг) */}
|
||||
<div className={`fw-bold mt-1 ${isActive ? 'text-white' : 'text-success'}`} style={{ fontSize: '1.1rem' }}>
|
||||
{ping}
|
||||
{ping != null ? ping : '—'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -846,7 +916,12 @@ function EasySwitchManager() {
|
||||
{server.gateways.map((gw, idx) => {
|
||||
const isActive = activeGw === gw.name;
|
||||
const isFastest = idx === 0;
|
||||
const ping = 20 + idx * 10 + Math.floor(Math.random() * 15);
|
||||
const pingKey = (() => {
|
||||
const inv = getServerMetadata(server.name);
|
||||
const routerId = inv?.id || inv?.dns || inv?.ip;
|
||||
return routerId && gw.ip ? `${routerId}:${gw.ip}` : null;
|
||||
})();
|
||||
const ping = pingKey && pingMap[pingKey] !== undefined ? pingMap[pingKey] : null;
|
||||
|
||||
return (
|
||||
<div key={gw.name} className="col-12 col-sm-4">
|
||||
@@ -920,7 +995,7 @@ function EasySwitchManager() {
|
||||
|
||||
{/* Метрика (пинг) */}
|
||||
<div className={`fw-bold mt-1 ${isActive ? 'text-white' : 'text-success'}`} style={{ fontSize: '1.1rem' }}>
|
||||
{ping}
|
||||
{ping != null ? ping : '—'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -970,7 +1045,12 @@ function EasySwitchManager() {
|
||||
{server.gateways.map((gw, idx) => {
|
||||
const isActive = activeGw === gw.name;
|
||||
const isFastest = idx === 0;
|
||||
const ping = 20 + idx * 10 + Math.floor(Math.random() * 15);
|
||||
const pingKey = (() => {
|
||||
const inv = getServerMetadata(server.name);
|
||||
const routerId = inv?.id || inv?.dns || inv?.ip;
|
||||
return routerId && gw.ip ? `${routerId}:${gw.ip}` : null;
|
||||
})();
|
||||
const ping = pingKey && pingMap[pingKey] !== undefined ? pingMap[pingKey] : null;
|
||||
|
||||
return (
|
||||
<div key={gw.name} className="col-12 col-sm-4">
|
||||
@@ -1044,7 +1124,7 @@ function EasySwitchManager() {
|
||||
|
||||
{/* Метрика (пинг) */}
|
||||
<div className={`fw-bold mt-1 ${isActive ? 'text-white' : 'text-success'}`} style={{ fontSize: '1.1rem' }}>
|
||||
{ping}
|
||||
{ping != null ? ping : '—'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user