Skip to content

Commit 4b7a40e

Browse files
committed
WUIP
1 parent bec803f commit 4b7a40e

File tree

3 files changed

+106
-11
lines changed

3 files changed

+106
-11
lines changed

site/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
"dependencies": {
3131
"@emoji-mart/data": "1.0.5",
3232
"@emoji-mart/react": "1.0.1",
33+
"@fastly/performance-observer-polyfill": "^2.0.0",
3334
"@fontsource/ibm-plex-mono": "4.5.10",
3435
"@fontsource/inter": "4.5.11",
3536
"@material-ui/core": "4.12.1",

site/src/contexts/ProxyContext.tsx

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import { useQuery } from "@tanstack/react-query"
22
import { getWorkspaceProxies } from "api/api"
33
import { Region } from "api/typesGenerated"
4-
import axios from "axios"
54
import { useDashboard } from "components/Dashboard/DashboardProvider"
6-
import { PerformanceObserver } from "perf_hooks"
5+
import PerformanceObserver from "@fastly/performance-observer-polyfill"
76
import {
87
createContext,
98
FC,
109
PropsWithChildren,
1110
useContext,
1211
useEffect,
12+
useReducer,
1313
useState,
1414
} from "react"
15+
import axios from "axios"
1516

1617
interface ProxyContextValue {
1718
proxy: PreferredProxy
@@ -43,6 +44,20 @@ export const ProxyContext = createContext<ProxyContextValue | undefined>(
4344
undefined,
4445
)
4546

47+
interface ProxyLatencyAction {
48+
proxyID: string
49+
latencyMS: number
50+
}
51+
52+
const proxyLatenciesReducer = (
53+
state: Record<string, number>,
54+
action: ProxyLatencyAction,
55+
): Record<string, number> => {
56+
// Just overwrite any existing latency.
57+
state[action.proxyID] = action.latencyMS
58+
return state
59+
}
60+
4661
/**
4762
* ProxyProvider interacts with local storage to indicate the preferred workspace proxy.
4863
*/
@@ -57,9 +72,10 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
5772
}
5873

5974
const [proxy, setProxy] = useState<PreferredProxy>(savedProxy)
60-
const [proxyLatenciesMS, setProxyLatenciesMS] = useState<
61-
Record<string, number>
62-
>({})
75+
const [proxyLatenciesMS, dispatchProxyLatenciesMS] = useReducer(
76+
proxyLatenciesReducer,
77+
{},
78+
)
6379

6480
const dashboard = useDashboard()
6581
const experimentEnabled = dashboard?.experiments.includes("moons")
@@ -87,14 +103,85 @@ export const ProxyProvider: FC<PropsWithChildren> = ({ children }) => {
87103
return
88104
}
89105

90-
window.performance.getEntries().forEach((entry) => {
91-
console.log(entry)
106+
// proxyMap is a map of the proxy path_app_url to the proxy object.
107+
// This is for the observer to know which requests are important to
108+
// record.
109+
const proxyChecks = proxiesResp.regions.reduce((acc, proxy) => {
110+
if (!proxy.healthy) {
111+
return acc
112+
}
113+
114+
const url = new URL("/healthz", proxy.path_app_url)
115+
acc[url.toString()] = proxy
116+
return acc
117+
}, {} as Record<string, Region>)
118+
119+
// Start a new performance observer to record of all the requests
120+
// to the proxies.
121+
const observer = new PerformanceObserver((list) => {
122+
list.getEntries().forEach((entry) => {
123+
if (entry.entryType !== "resource") {
124+
// We should never get these, but just in case.
125+
return
126+
}
127+
128+
const check = proxyChecks[entry.name]
129+
if (!check) {
130+
// This is not a proxy request.
131+
return
132+
}
133+
// These docs are super useful.
134+
// https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Resource_timing
135+
// dispatchProxyLatenciesMS({
136+
// proxyID: check.id,
137+
// latencyMS: entry.duration,
138+
// })
139+
140+
console.log("performance observer entry", entry)
141+
})
142+
console.log("performance observer", list)
92143
})
93-
const observer = new PerformanceObserver((list, observer) => {
94-
console.log("performance observer", list, observer)
144+
// The resource requests include xmlhttp requests.
145+
observer.observe({ entryTypes: ["resource"] })
146+
axios
147+
.get("https://dev.coder.com/healthz")
148+
.then((resp) => {
149+
console.log(resp)
150+
})
151+
.catch((err) => {
152+
console.log(err)
153+
})
154+
155+
const proxyChecks = proxiesResp.regions.map((proxy) => {
156+
// TODO: Move to /derp/latency-check
157+
const url = new URL("/healthz", proxy.path_app_url)
158+
return axios
159+
.get(url.toString())
160+
.then((resp) => {
161+
return resp
162+
})
163+
.catch((err) => {
164+
return err
165+
})
166+
167+
// Add a random query param to ensure the request is not cached.
168+
// url.searchParams.append("cache_bust", Math.random().toString())
95169
})
96170

97-
observer.observe({ entryTypes: ["http2", "http"] })
171+
Promise.all([proxyChecks])
172+
.then((resp) => {
173+
console.log(resp)
174+
console.log("done", observer.takeRecords())
175+
// observer.disconnect()
176+
})
177+
.catch((err) => {
178+
console.log(err)
179+
// observer.disconnect()
180+
})
181+
.finally(() => {
182+
console.log("finally", observer.takeRecords())
183+
// observer.disconnect()
184+
})
98185
}, [proxiesResp])
99186

100187
const setAndSaveProxy = (

site/yarn.lock

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,13 @@
13471347
resolved "https://registry.yarnpkg.com/@fal-works/esbuild-plugin-global-externals/-/esbuild-plugin-global-externals-2.1.2.tgz#c05ed35ad82df8e6ac616c68b92c2282bd083ba4"
13481348
integrity sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==
13491349

1350+
"@fastly/performance-observer-polyfill@^2.0.0":
1351+
version "2.0.0"
1352+
resolved "https://registry.yarnpkg.com/@fastly/performance-observer-polyfill/-/performance-observer-polyfill-2.0.0.tgz#fb697180f92019119d8c55d20216adce6436f941"
1353+
integrity sha512-cQC4E6ReYY4Vud+eCJSCr1N0dSz+fk7xJlLiSgPFDHbnFLZo5DenazoersMt9D8JkEhl9Z5ZwJ/8apcjSrdb8Q==
1354+
dependencies:
1355+
tslib "^2.0.3"
1356+
13501357
"@fontsource/ibm-plex-mono@4.5.10":
13511358
version "4.5.10"
13521359
resolved "https://registry.yarnpkg.com/@fontsource/ibm-plex-mono/-/ibm-plex-mono-4.5.10.tgz#25d004646853bf46b3787341300662fe61f8ad78"
@@ -11521,7 +11528,7 @@ tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.3:
1152111528
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
1152211529
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
1152311530

11524-
tslib@^2, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0:
11531+
tslib@^2, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0:
1152511532
version "2.5.0"
1152611533
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
1152711534
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==

0 commit comments

Comments
 (0)