mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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:
+2
-2
@@ -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} />
|
||||||
|
|||||||
@@ -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() }
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
Reference in New Issue
Block a user