94 lines
2.8 KiB
TypeScript
94 lines
2.8 KiB
TypeScript
import { useEffect, useMemo } from 'react';
|
|
import { useNodeCheckQuery } from '../utils/__generated__/NodeCheck';
|
|
import { useHeaderStore } from '@vegaprotocol/apollo-client';
|
|
import { useEnvironment } from './use-environment';
|
|
import { useNavigatorOnline } from '@vegaprotocol/react-helpers';
|
|
import { Intent } from '@vegaprotocol/ui-toolkit';
|
|
import { isTestEnv } from '@vegaprotocol/utils';
|
|
import { useT } from '../use-t';
|
|
|
|
const POLL_INTERVAL = 1000;
|
|
const BLOCK_THRESHOLD = 3;
|
|
const ERROR_LATENCY = 10000;
|
|
const WARNING_LATENCY = 3000;
|
|
|
|
export const useNodeHealth = () => {
|
|
const t = useT();
|
|
const online = useNavigatorOnline();
|
|
const url = useEnvironment((store) => store.VEGA_URL);
|
|
const headerStore = useHeaderStore();
|
|
const headers = url ? headerStore[url] : undefined;
|
|
const { data, error, startPolling, stopPolling } = useNodeCheckQuery({
|
|
fetchPolicy: 'no-cache',
|
|
});
|
|
|
|
const blockDiff = useMemo(() => {
|
|
if (!data?.statistics?.blockHeight) {
|
|
return null;
|
|
}
|
|
|
|
if (!headers?.blockHeight) {
|
|
return 0;
|
|
}
|
|
|
|
return Number(data.statistics.blockHeight) - headers.blockHeight;
|
|
}, [data?.statistics?.blockHeight, headers?.blockHeight]);
|
|
|
|
useEffect(() => {
|
|
if (error) {
|
|
stopPolling();
|
|
return;
|
|
}
|
|
|
|
if (!isTestEnv() && window.location.hostname !== 'localhost') {
|
|
startPolling(POLL_INTERVAL);
|
|
}
|
|
}, [error, startPolling, stopPolling]);
|
|
|
|
const blockUpdateMsLatency = headers?.timestamp
|
|
? Date.now() - headers.timestamp.getTime()
|
|
: 0;
|
|
|
|
const [text, intent] = useMemo(() => {
|
|
let intent = Intent.Success;
|
|
let text = t('Operational');
|
|
|
|
if (!online) {
|
|
text = t('Offline');
|
|
intent = Intent.Danger;
|
|
} else if (blockDiff === null) {
|
|
// Block height query failed and null was returned
|
|
text = t('Non operational');
|
|
intent = Intent.Danger;
|
|
} else if (blockUpdateMsLatency > ERROR_LATENCY) {
|
|
text = t(
|
|
'Erroneous latency ( >{{errorLatency}} sec): {{blockUpdateLatency}} sec',
|
|
{
|
|
errorLatency: (ERROR_LATENCY / 1000).toString(),
|
|
blockUpdateLatency: (blockUpdateMsLatency / 1000).toFixed(2),
|
|
}
|
|
);
|
|
intent = Intent.Danger;
|
|
} else if (blockDiff >= BLOCK_THRESHOLD) {
|
|
text = t('blocksBehind', '{{count}} Blocks behind', { count: blockDiff });
|
|
intent = Intent.Warning;
|
|
} else if (blockUpdateMsLatency > WARNING_LATENCY) {
|
|
text = t(
|
|
'Warning delay ( >{{warningLatency}} sec): {{blockUpdateLatency}} sec',
|
|
{
|
|
warningLatency: (WARNING_LATENCY / 1000).toString(),
|
|
blockUpdateLatency: (blockUpdateMsLatency / 1000).toFixed(2),
|
|
}
|
|
);
|
|
intent = Intent.Warning;
|
|
}
|
|
return [text, intent];
|
|
}, [online, blockDiff, blockUpdateMsLatency, t]);
|
|
|
|
return {
|
|
datanodeBlockHeight: headers?.blockHeight,
|
|
text,
|
|
intent,
|
|
};
|
|
};
|