chore: add function to refetch latencies to ProxyContext (#7769)

* Allow refetching of proxy latencies
* Pass refetch funtion up the context stack
* Add to menu bar
This commit is contained in:
Steven Masley
2023-06-01 13:37:20 +00:00
committed by GitHub
parent cf8d2bc096
commit b32ed2d97e
11 changed files with 52 additions and 12 deletions
+2 -2
View File
@@ -19,7 +19,7 @@ jest.mock("contexts/useProxyLatency", () => ({
useProxyLatency: (proxies?: RegionsResponse) => { useProxyLatency: (proxies?: RegionsResponse) => {
// Must use `useMemo` here to avoid infinite loop. // Must use `useMemo` here to avoid infinite loop.
// Mocking the hook with a hook. // Mocking the hook with a hook.
const latencies = useMemo(() => { const proxyLatencies = useMemo(() => {
if (!proxies) { if (!proxies) {
return {} as Record<string, ProxyLatencyReport> return {} as Record<string, ProxyLatencyReport>
} }
@@ -35,7 +35,7 @@ jest.mock("contexts/useProxyLatency", () => ({
}, {} as Record<string, ProxyLatencyReport>) }, {} as Record<string, ProxyLatencyReport>)
}, [proxies]) }, [proxies])
return latencies return { proxyLatencies, refetch: jest.fn() }
}, },
})) }))
@@ -29,6 +29,9 @@ const Template: Story<AppLinkProps> = (args) => (
clearProxy: () => { clearProxy: () => {
return return
}, },
refetchProxyLatencies: () => {
return
},
}} }}
> >
<AppLink {...args} /> <AppLink {...args} />
@@ -19,6 +19,7 @@ const proxyContextValue: ProxyContextValue = {
isFetched: true, isFetched: true,
setProxy: jest.fn(), setProxy: jest.fn(),
clearProxy: action("clearProxy"), clearProxy: action("clearProxy"),
refetchProxyLatencies: jest.fn(),
proxyLatencies: {}, proxyLatencies: {},
} }
@@ -189,6 +189,7 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
const buttonRef = useRef<HTMLButtonElement>(null) const buttonRef = useRef<HTMLButtonElement>(null)
const [isOpen, setIsOpen] = useState(false) const [isOpen, setIsOpen] = useState(false)
const selectedProxy = proxyContextValue.proxy.proxy const selectedProxy = proxyContextValue.proxy.proxy
const refreshLatencies = proxyContextValue.refetchProxyLatencies
const closeMenu = () => setIsOpen(false) const closeMenu = () => setIsOpen(false)
const navigate = useNavigate() const navigate = useNavigate()
@@ -293,6 +294,9 @@ const ProxyMenu: FC<{ proxyContextValue: ProxyContextValue }> = ({
> >
Proxy settings Proxy settings
</MenuItem> </MenuItem>
<MenuItem sx={{ fontSize: 14 }} onClick={refreshLatencies}>
Refresh Latencies
</MenuItem>
</Menu> </Menu>
</> </>
) )
@@ -68,6 +68,9 @@ const TemplateFC = (
clearProxy: () => { clearProxy: () => {
return return
}, },
refetchProxyLatencies: () => {
return
},
}} }}
> >
<AgentRow {...args} /> <AgentRow {...args} />
@@ -33,6 +33,9 @@ Example.args = {
clearProxy: () => { clearProxy: () => {
return return
}, },
refetchProxyLatencies: () => {
return
},
}} }}
> >
<AgentRow <AgentRow
@@ -103,6 +106,9 @@ BunchOfMetadata.args = {
clearProxy: () => { clearProxy: () => {
return return
}, },
refetchProxyLatencies: () => {
return
},
}} }}
> >
<AgentRow <AgentRow
@@ -53,6 +53,9 @@ const Template: Story<WorkspaceProps> = (args) => (
setProxy: () => { setProxy: () => {
return return
}, },
refetchProxyLatencies: () => {
return
},
}} }}
> >
<Workspace {...args} /> <Workspace {...args} />
+1 -1
View File
@@ -26,7 +26,7 @@ import userEvent from "@testing-library/user-event"
// here and not inside a unit test. // here and not inside a unit test.
jest.mock("contexts/useProxyLatency", () => ({ jest.mock("contexts/useProxyLatency", () => ({
useProxyLatency: () => { useProxyLatency: () => {
return hardCodedLatencies return { proxyLatencies: hardCodedLatencies, refetch: jest.fn() }
}, },
})) }))
+6 -1
View File
@@ -45,6 +45,9 @@ export interface ProxyContextValue {
// then the latency has not been fetched yet. Calculations happen async for each proxy in the list. // then the latency has not been fetched yet. Calculations happen async for each proxy in the list.
// Refer to the returned report for a given proxy for more information. // Refer to the returned report for a given proxy for more information.
proxyLatencies: Record<string, ProxyLatencyReport> proxyLatencies: Record<string, ProxyLatencyReport>
// refetchProxyLatencies will trigger refreshing of the proxy latencies. By default the latencies
// are loaded once.
refetchProxyLatencies: () => void
// setProxy is a function that sets the user's selected proxy. This function should // setProxy is a function that sets the user's selected proxy. This function should
// only be called if the user is manually selecting a proxy. This value is stored in local // only be called if the user is manually selecting a proxy. This value is stored in local
// storage and will persist across reloads and tabs. // storage and will persist across reloads and tabs.
@@ -101,7 +104,8 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
// Every time we get a new proxiesResponse, update the latency check // Every time we get a new proxiesResponse, update the latency check
// to each workspace proxy. // to each workspace proxy.
const proxyLatencies = useProxyLatency(proxiesResp) const { proxyLatencies, refetch: refetchProxyLatencies } =
useProxyLatency(proxiesResp)
// updateProxy is a helper function that when called will // updateProxy is a helper function that when called will
// update the proxy being used. // update the proxy being used.
@@ -128,6 +132,7 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
<ProxyContext.Provider <ProxyContext.Provider
value={{ value={{
proxyLatencies, proxyLatencies,
refetchProxyLatencies,
userProxy: userSavedProxy, userProxy: userSavedProxy,
proxy: experimentEnabled proxy: experimentEnabled
? proxy ? proxy
+22 -8
View File
@@ -1,5 +1,5 @@
import { Region, RegionsResponse } from "api/typesGenerated" import { Region, RegionsResponse } from "api/typesGenerated"
import { useEffect, useReducer } from "react" import { useEffect, useReducer, useState } from "react"
import PerformanceObserver from "@fastly/performance-observer-polyfill" import PerformanceObserver from "@fastly/performance-observer-polyfill"
import axios from "axios" import axios from "axios"
import { generateRandomString } from "utils/random" import { generateRandomString } from "utils/random"
@@ -25,20 +25,31 @@ const proxyLatenciesReducer = (
action: ProxyLatencyAction, action: ProxyLatencyAction,
): Record<string, ProxyLatencyReport> => { ): Record<string, ProxyLatencyReport> => {
// Just overwrite any existing latency. // Just overwrite any existing latency.
return { state[action.proxyID] = action.report
...state, return state
[action.proxyID]: action.report,
}
} }
export const useProxyLatency = ( export const useProxyLatency = (
proxies?: RegionsResponse, proxies?: RegionsResponse,
): Record<string, ProxyLatencyReport> => { ): {
// Refetch can be called to refetch the proxy latencies.
// Until the new values are loaded, the old values will still be used.
refetch: () => void
proxyLatencies: Record<string, ProxyLatencyReport>
} => {
const [proxyLatencies, dispatchProxyLatencies] = useReducer( const [proxyLatencies, dispatchProxyLatencies] = useReducer(
proxyLatenciesReducer, proxyLatenciesReducer,
{}, {},
) )
// This latestFetchRequest is used to trigger a refetch of the proxy latencies.
const [latestFetchRequest, setLatestFetchRequest] = useState(
new Date().toISOString(),
)
const refetch = () => {
setLatestFetchRequest(new Date().toISOString())
}
// Only run latency updates when the proxies change. // Only run latency updates when the proxies change.
useEffect(() => { useEffect(() => {
if (!proxies) { if (!proxies) {
@@ -148,7 +159,10 @@ export const useProxyLatency = (
// via the performance observer. So we can disconnect the observer. // via the performance observer. So we can disconnect the observer.
observer.disconnect() observer.disconnect()
}) })
}, [proxies]) }, [proxies, latestFetchRequest])
return proxyLatencies return {
proxyLatencies,
refetch,
}
} }
@@ -55,6 +55,7 @@ const renderTerminal = () => {
isLoading: false, isLoading: false,
setProxy: jest.fn(), setProxy: jest.fn(),
clearProxy: jest.fn(), clearProxy: jest.fn(),
refetchProxyLatencies: jest.fn(),
}} }}
> >
<TerminalPage renderer="dom" /> <TerminalPage renderer="dom" />