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, 1.); | |
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, progress: number) { | |
// send measurements to analytics API | |
const measurements = { | |
bandwidth: bytesPerSecond, | |
latency, | |
location, | |
progress | |
}; | |
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); | |
}); | |
}); | |
} | |