Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
| // place files you want to import through the `$lib` alias in this folder. | |
| import { majorAirportIATAs } from '$lib/icao'; | |
| interface BandwidthCallback { | |
| ( | |
| elapsedMs: number, | |
| loadedBytes: number, | |
| totalBytes: number, | |
| bytesPerSecond: number, | |
| done: boolean | |
| ): boolean; | |
| } | |
| export async function bandwidthTest( | |
| onProgress: BandwidthCallback, | |
| onLatency: (latency: number) => void, | |
| onServerLocation: (location: string) => void | |
| ) { | |
| // performance.setResourceTimingBufferSize(100); | |
| // performance.clearResourceTimings(); | |
| const url = 'https://cdn-test-cloudfront.hf.co/5gb.safetensors'; | |
| // const url = 'https://cdn-test-cloudfront.hf.co/15mb.json'; | |
| // issue HEAD requests to estimate latency (round trip time), and average | |
| let latencySum = 0; | |
| const numLatencyTests = 5; | |
| for (let i = 0; i < numLatencyTests; i++) { | |
| const startTime = performance.now(); | |
| const response = await fetch(url, { method: 'HEAD' }); | |
| if (!response.ok) { | |
| throw new Error(`Network response was not ok: ${response.status}`); | |
| } | |
| const latency = performance.now() - startTime; | |
| latencySum += latency; | |
| } | |
| onLatency(latencySum / numLatencyTests); | |
| const startTime = performance.now(); | |
| const response = await fetch(url); | |
| if (!response.ok) { | |
| throw new Error(`Network response was not ok: ${response.status}`); | |
| } | |
| // setTimeout(() => { | |
| // const entries = performance.getEntriesByType('resource'); | |
| // const resourceEntry = entries.find((e) => e.name === url); | |
| // if (!resourceEntry) { | |
| // return | |
| // } | |
| // console.log(resourceEntry); | |
| // const { requestStart, responseStart } = resourceEntry; | |
| // const latency = responseStart - requestStart; | |
| // onLatency(latency); | |
| // }, 2000); | |
| // extract content-length | |
| const contentLengthHeader = response.headers.get('content-length'); | |
| const totalBytes = contentLengthHeader ? parseInt(contentLengthHeader, 10) : 1e99; | |
| // extract pop location | |
| let cdnPop = response.headers.get('x-amz-cf-pop'); | |
| if (cdnPop !== null) { | |
| cdnPop = cdnPop.toUpperCase().slice(0, 3); | |
| // try to map to IATA | |
| if (cdnPop in majorAirportIATAs) { | |
| cdnPop = majorAirportIATAs[cdnPop].city + ', ' + majorAirportIATAs[cdnPop].country; | |
| } else { | |
| cdnPop = 'Unknown'; | |
| } | |
| } else { | |
| cdnPop = 'Unknown'; | |
| } | |
| onServerLocation(cdnPop); | |
| const reader = response.body.getReader(); | |
| let loadedBytes = 0; | |
| let lastTimestamp = performance.now(); | |
| let lastLoaded = 0; | |
| const REPORT_INTERVAL_MS = 500; | |
| onProgress(0, loadedBytes, totalBytes, 0, false); | |
| let bytesPerSecond = 0; | |
| while (true) { | |
| const { done, value } = await reader.read(); | |
| if (done) { | |
| // stream is finished | |
| const elapsedMs = performance.now() - startTime; | |
| onProgress(elapsedMs, loadedBytes, totalBytes, bytesPerSecond, true); | |
| // send analytics data | |
| await sendAnalyticsData(bytesPerSecond, latencySum / numLatencyTests, cdnPop); | |
| break; | |
| } | |
| // `value` is a Uint8Array for this chunk | |
| loadedBytes += value.byteLength; | |
| // Current time | |
| const now = performance.now(); | |
| const deltaMs = now - lastTimestamp; | |
| if (deltaMs >= REPORT_INTERVAL_MS) { | |
| // compute bytes downloaded since last report | |
| const deltaBytes = loadedBytes - lastLoaded; | |
| // convert ms to seconds | |
| const deltaSeconds = deltaMs / 1000; | |
| bytesPerSecond = deltaBytes / deltaSeconds; | |
| // Invoke callback | |
| const elapsedMs = performance.now() - startTime; | |
| const stop = onProgress(elapsedMs, loadedBytes, totalBytes, bytesPerSecond, false); | |
| if (stop) { | |
| // stop the test | |
| console.log(`Stopping bandwidth test at ${loadedBytes} bytes after ${elapsedMs} ms`); | |
| break; | |
| } | |
| // Reset our “last” markers | |
| lastLoaded = loadedBytes; | |
| lastTimestamp = now; | |
| } | |
| } | |
| } | |
| interface ClientInfo { | |
| clientIp: string; | |
| clientLocation: string; | |
| } | |
| export async function getClientInfo(): Promise<ClientInfo> { | |
| let clientIp = 'Detecting...'; | |
| let clientLocation = 'Detecting...'; | |
| const res = await fetch('https://ipapi.co/json/'); | |
| clientIp = 'Not available'; | |
| clientLocation = 'Not available'; | |
| if (res.ok) { | |
| const data = await res.json(); | |
| clientIp = data.ip || 'Unknown'; | |
| let location = ''; | |
| if (data.city) location += data.city + ', '; | |
| if (data.region) location += data.region + ', '; | |
| if (data.country_name) location += data.country_name; | |
| clientLocation = location || 'Unknown'; | |
| } | |
| return new Promise((resolve) => | |
| resolve({ | |
| clientIp, | |
| clientLocation | |
| }) | |
| ); | |
| } | |
| export async function sendAnalyticsData(bytesPerSecond: number, latency: number, location: string) { | |
| // send measurements to analytics API | |
| const measurements = { | |
| bandwidth: bytesPerSecond, | |
| latency, | |
| location | |
| }; | |
| console.log('Sending analytics data'); | |
| return new Promise((resolve) => { | |
| fetch('/analytics', { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json' | |
| }, | |
| body: JSON.stringify(measurements) | |
| }) | |
| .then((response) => { | |
| if (!response.ok) { | |
| throw new Error(`Network response was not ok: ${response.status}`); | |
| } | |
| resolve(response); | |
| }) | |
| .catch((error) => { | |
| console.error('Error sending bandwidth data:', error); | |
| resolve(null); | |
| }); | |
| }); | |
| } | |