feat(smartnetwork): add Rust-powered network diagnostics bridge and IP intelligence lookups
This commit is contained in:
@@ -53,7 +53,7 @@ export class CloudflareSpeed {
|
||||
const t5 = await measureDownloadParallel(100001000, 1);
|
||||
downloadTests = [...t1, ...t2, ...t3, ...t4, ...t5];
|
||||
}
|
||||
const speedDownload = stats.quartile(downloadTests, 0.9).toFixed(2);
|
||||
const speedDownload = downloadTests.length > 0 ? stats.quartile(downloadTests, 0.9).toFixed(2) : '0.00';
|
||||
|
||||
// lets test the upload speed with configurable parallel streams
|
||||
const measureUploadParallel = (bytes: number, iterations: number) => {
|
||||
@@ -84,7 +84,7 @@ export class CloudflareSpeed {
|
||||
const u3 = await measureUploadParallel(1001000, 8);
|
||||
uploadTests = [...u1, ...u2, ...u3];
|
||||
}
|
||||
const speedUpload = stats.quartile(uploadTests, 0.9).toFixed(2);
|
||||
const speedUpload = uploadTests.length > 0 ? stats.quartile(uploadTests, 0.9).toFixed(2) : '0.00';
|
||||
|
||||
return {
|
||||
...latency,
|
||||
@@ -147,8 +147,14 @@ export class CloudflareSpeed {
|
||||
for (let i = 0; i < iterations; i += 1) {
|
||||
await this.upload(bytes).then(
|
||||
async (response) => {
|
||||
const transferTime = response[6];
|
||||
measurements.push(await this.measureSpeed(bytes, transferTime));
|
||||
// Prefer server-timing duration; fall back to client-side transfer time
|
||||
let transferTime = response[6];
|
||||
if (!transferTime || !isFinite(transferTime)) {
|
||||
transferTime = response[5] - response[4]; // ended - ttfb
|
||||
}
|
||||
if (transferTime > 0) {
|
||||
measurements.push(await this.measureSpeed(bytes, transferTime));
|
||||
}
|
||||
},
|
||||
(error) => {
|
||||
getLogger().error('Error measuring upload chunk:', error);
|
||||
@@ -164,17 +170,22 @@ export class CloudflareSpeed {
|
||||
}
|
||||
|
||||
public async fetchServerLocations(): Promise<{ [key: string]: string }> {
|
||||
const res = JSON.parse(await this.get('speed.cloudflare.com', '/locations')) as Array<{
|
||||
iata: string;
|
||||
city: string;
|
||||
}>;
|
||||
return res.reduce(
|
||||
(data: Record<string, string>, optionsArg) => {
|
||||
data[optionsArg.iata] = optionsArg.city;
|
||||
return data;
|
||||
},
|
||||
{} as Record<string, string>,
|
||||
);
|
||||
try {
|
||||
const raw = await this.get('speed.cloudflare.com', '/locations');
|
||||
const parsed = JSON.parse(raw);
|
||||
if (!Array.isArray(parsed)) {
|
||||
return {};
|
||||
}
|
||||
return (parsed as Array<{ iata: string; city: string }>).reduce(
|
||||
(data: Record<string, string>, entry) => {
|
||||
data[entry.iata] = entry.city;
|
||||
return data;
|
||||
},
|
||||
{} as Record<string, string>,
|
||||
);
|
||||
} catch {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
public async get(hostname: string, path: string): Promise<string> {
|
||||
@@ -259,7 +270,12 @@ export class CloudflareSpeed {
|
||||
sslHandshake,
|
||||
ttfb,
|
||||
ended,
|
||||
parseFloat((res.headers['server-timing'] as string).slice(22)),
|
||||
(() => {
|
||||
const serverTiming = res.headers['server-timing'] as string | undefined;
|
||||
if (!serverTiming) return 0;
|
||||
const match = serverTiming.match(/dur=([\d.]+)/);
|
||||
return match ? parseFloat(match[1]) : parseFloat(serverTiming.slice(22)) || 0;
|
||||
})(),
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user