Skip to content

Commit

Permalink
Merge pull request #89 from spacemeshos/fix-avoid-retry-spam
Browse files Browse the repository at this point in the history
Avoid spam requests when fetching network status or account data
  • Loading branch information
brusherru authored Sep 18, 2024
2 parents 246b0e9 + 6b4aac8 commit e7d2fab
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 11 deletions.
13 changes: 11 additions & 2 deletions src/hooks/useDataRefresher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { singletonHook } from 'react-singleton-hook';
import { O } from '@mobily/ts-belt';

import useNetworks from '../store/useNetworks';
import useNetworkStatus from '../store/useNetworkStatus';
import useWallet from '../store/useWallet';
import { Bech32Address } from '../types/common';
import { API_MIN_FETCH_INTERVAL } from '../utils/constants';
import { noop } from '../utils/func';

import useAccountHandlers from './useAccountHandlers';
Expand All @@ -25,15 +27,20 @@ const useDataRefresher = () => {
const accounts = useAccountsList(hrp);
const { selectedAccount } = useWallet();
const currentNetwork = getCurrentNetwork();
const { status } = useNetworkStatus();
const addresses = useMemo(
() => accounts.map((acc) => acc.address),
[accounts]
);
const curAddress = accounts[selectedAccount]?.address;
const rpc = currentNetwork?.jsonRPC;

const cannotDoRequest = !status || !rpc;
const doRequests = useMemo(
() => (addrs: Bech32Address[], addr: Bech32Address) => {
if (cannotDoRequest) {
return Promise.resolve();
}
setIsLoading(true);
return Promise.all([
fetchAccountState(addrs),
Expand All @@ -48,7 +55,7 @@ const useDataRefresher = () => {
setIsLoading(false);
});
},
[fetchAccountState, fetchTransactions, fetchRewards]
[cannotDoRequest, fetchAccountState, fetchTransactions, fetchRewards]
);

useEffect(() => {
Expand All @@ -57,7 +64,9 @@ const useDataRefresher = () => {
doRequests(addresses, curAddress);
ival = setInterval(
() => doRequests(addresses, curAddress),
O.getWithDefault(layerDur, 300) * 1000
O.mapWithDefault(layerDur, 300, (val) =>
val < API_MIN_FETCH_INTERVAL ? API_MIN_FETCH_INTERVAL : val
) * 1000
);
}
return () => clearInterval(ival);
Expand Down
42 changes: 33 additions & 9 deletions src/store/useNetworkStatus.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,71 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { singletonHook } from 'react-singleton-hook';
import { create } from 'zustand';

import { O } from '@mobily/ts-belt';

import { fetchNodeStatus } from '../api/requests/netinfo';
import { NodeStatus } from '../types/networks';
import { MINUTE } from '../utils/constants';
import {
FETCH_NODE_STATUS_INTERVAL,
FETCH_NODE_STATUS_RETRY,
} from '../utils/constants';
import { noop } from '../utils/func';

import useNetworks from './useNetworks';

type StoreState = {
status: NodeStatus | null;
error: Error | null;
lastUpdate: number;
setStatus: (status: NodeStatus) => void;
setError: (error: Error) => void;
};

const useNetworkStatusStore = create<StoreState>((set) => ({
status: null,
error: null,
setStatus: (status: NodeStatus) => set({ status, error: null }),
setError: (error: Error) => set({ status: null, error }),
lastUpdate: 0,
setStatus: (status: NodeStatus) =>
set({ status, error: null, lastUpdate: Date.now() }),
setError: (error: Error) =>
set({ status: null, error, lastUpdate: Date.now() }),
}));

const useNetworkStatus = () => {
const { getCurrentNetwork } = useNetworks();
const currentNetwork = getCurrentNetwork();
const { status, error, setStatus, setError } = useNetworkStatusStore();

const { status, error, lastUpdate, setStatus, setError } =
useNetworkStatusStore();
const rpc = O.mapWithDefault(currentNetwork, '', (net) => net.jsonRPC);

const [prevNet, setPrevNet] = useState(currentNetwork);
const isNewNetwork = prevNet !== currentNetwork;

useEffect(() => {
setPrevNet(currentNetwork);
}, [currentNetwork, setPrevNet]);

useEffect(() => {
if (!rpc) return noop;

const fetchStatus = () => {
fetchNodeStatus(rpc).then(setStatus).catch(setError);
if (
isNewNetwork ||
!lastUpdate ||
Date.now() - lastUpdate > FETCH_NODE_STATUS_INTERVAL
) {
fetchNodeStatus(rpc).then(setStatus).catch(setError);
}
};

fetchStatus();
const ival = setInterval(fetchStatus, 5 * MINUTE);
const ival = setInterval(
fetchStatus,
status ? FETCH_NODE_STATUS_INTERVAL : FETCH_NODE_STATUS_RETRY
);
return () => clearInterval(ival);
}, [rpc, setError, setStatus]);
}, [lastUpdate, rpc, setError, setStatus, status, isNewNetwork]);

return { status, error };
};
Expand Down
5 changes: 5 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export const MAIN_MENU_BUTTONS_SIZE = { base: 18, md: 24 };

export const MAX_MULTISIG_AMOUNT = 10;

export const API_MIN_FETCH_INTERVAL = 10;

export const FETCH_NODE_STATUS_INTERVAL = 5 * MINUTE;
export const FETCH_NODE_STATUS_RETRY = 1 * MINUTE;

export const GENESIS_VESTING_ACCOUNTS = {
sm1qqqqqqpdvm9pwx07d99ajgnuj8rp250u90xt4jczwd873: 2743200000000000n,
sm1qqqqqqx4shtr69586rtnx2j69hvsp9yeen0q8asqv7duy: 5867100000000000n,
Expand Down

0 comments on commit e7d2fab

Please sign in to comment.