( proxies?: readonly Region[], )
| 41 | }; |
| 42 | |
| 43 | export const useProxyLatency = ( |
| 44 | proxies?: readonly Region[], |
| 45 | ): { |
| 46 | // Refetch can be called to refetch the proxy latencies. |
| 47 | // Until the new values are loaded, the old values will still be used. |
| 48 | refetch: () => Date; |
| 49 | proxyLatencies: Record<string, ProxyLatencyReport>; |
| 50 | // loaded signals all latency requests have completed. Once set to true, this will not change. |
| 51 | // Latencies at this point should be loaded from local storage, and updated asynchronously as needed. |
| 52 | // If local storage has updated latencies, then this will be set to true with 0 actual network requests. |
| 53 | // The loaded latencies will all be from the cache. |
| 54 | loaded: boolean; |
| 55 | } => { |
| 56 | // maxStoredLatencies is the maximum number of latencies to store per proxy in local storage. |
| 57 | let maxStoredLatencies = 1; |
| 58 | // The reason we pull this from local storage is so for development purposes, a user can manually |
| 59 | // set a larger number to collect data in their normal usage. This data can later be analyzed to come up |
| 60 | // with some better magic numbers. |
| 61 | const maxStoredLatenciesVar = localStorage.getItem( |
| 62 | "workspace-proxy-latencies-max", |
| 63 | ); |
| 64 | if (maxStoredLatenciesVar) { |
| 65 | maxStoredLatencies = Number(maxStoredLatenciesVar); |
| 66 | } |
| 67 | |
| 68 | const [proxyLatencies, dispatchProxyLatencies] = useReducer( |
| 69 | proxyLatenciesReducer, |
| 70 | {}, |
| 71 | ); |
| 72 | |
| 73 | // This latestFetchRequest is used to trigger a refetch of the proxy latencies. |
| 74 | const [latestFetchRequest, setLatestFetchRequest] = useState( |
| 75 | // The initial state is the current time minus the interval. Any proxies that have a latency after this |
| 76 | // in the cache are still valid. |
| 77 | new Date(Date.now() - proxyIntervalSeconds * 1000).toISOString(), |
| 78 | ); |
| 79 | |
| 80 | const [loaded, setLoaded] = useState(false); |
| 81 | |
| 82 | // Refetch will always set the latestFetchRequest to the current time, making all the cached latencies |
| 83 | // stale and triggering a refetch of all proxies in the list. |
| 84 | const refetch = () => { |
| 85 | const d = new Date(); |
| 86 | setLatestFetchRequest(d.toISOString()); |
| 87 | return d; |
| 88 | }; |
| 89 | |
| 90 | // Only run latency updates when the proxies change. |
| 91 | useEffect(() => { |
| 92 | if (!proxies) { |
| 93 | return; |
| 94 | } |
| 95 | |
| 96 | const storedLatencies = loadStoredLatencies(); |
| 97 | |
| 98 | // proxyMap is a map of the proxy path_app_url to the proxy object. |
| 99 | // This is for the observer to know which requests are important to |
| 100 | // record. |
no test coverage detected