Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
feat: enhance analytics data handling with early event sending (after 5s)
Browse files- src/lib/index.ts +4 -3
- src/routes/+page.svelte +9 -11
- src/routes/analytics/+server.ts +6 -4
src/lib/index.ts
CHANGED
|
@@ -86,7 +86,7 @@ export async function bandwidthTest(
|
|
| 86 |
const elapsedMs = performance.now() - startTime;
|
| 87 |
onProgress(elapsedMs, loadedBytes, totalBytes, bytesPerSecond, true);
|
| 88 |
// send analytics data
|
| 89 |
-
await sendAnalyticsData(bytesPerSecond, latencySum / numLatencyTests, cdnPop);
|
| 90 |
break;
|
| 91 |
}
|
| 92 |
|
|
@@ -148,12 +148,13 @@ export async function getClientInfo(): Promise<ClientInfo> {
|
|
| 148 |
);
|
| 149 |
}
|
| 150 |
|
| 151 |
-
export async function sendAnalyticsData(bytesPerSecond: number, latency: number, location: string) {
|
| 152 |
// send measurements to analytics API
|
| 153 |
const measurements = {
|
| 154 |
bandwidth: bytesPerSecond,
|
| 155 |
latency,
|
| 156 |
-
location
|
|
|
|
| 157 |
};
|
| 158 |
console.log('Sending analytics data');
|
| 159 |
return new Promise((resolve) => {
|
|
|
|
| 86 |
const elapsedMs = performance.now() - startTime;
|
| 87 |
onProgress(elapsedMs, loadedBytes, totalBytes, bytesPerSecond, true);
|
| 88 |
// send analytics data
|
| 89 |
+
await sendAnalyticsData(bytesPerSecond, latencySum / numLatencyTests, cdnPop, 1.);
|
| 90 |
break;
|
| 91 |
}
|
| 92 |
|
|
|
|
| 148 |
);
|
| 149 |
}
|
| 150 |
|
| 151 |
+
export async function sendAnalyticsData(bytesPerSecond: number, latency: number, location: string, progress: number) {
|
| 152 |
// send measurements to analytics API
|
| 153 |
const measurements = {
|
| 154 |
bandwidth: bytesPerSecond,
|
| 155 |
latency,
|
| 156 |
+
location,
|
| 157 |
+
progress
|
| 158 |
};
|
| 159 |
console.log('Sending analytics data');
|
| 160 |
return new Promise((resolve) => {
|
src/routes/+page.svelte
CHANGED
|
@@ -77,6 +77,7 @@
|
|
| 77 |
};
|
| 78 |
|
| 79 |
let testTimeoutHandler = 0;
|
|
|
|
| 80 |
|
| 81 |
const startTest = () => {
|
| 82 |
testStatus = 'Running';
|
|
@@ -88,24 +89,21 @@
|
|
| 88 |
bandwidthTest(bandwidthCallback, latencyCallback, serverLocationCallback);
|
| 89 |
testTimeoutHandler = setTimeout(async () => {
|
| 90 |
console.log('Test timed out after', MaxTestDurationSec, 'seconds');
|
|
|
|
|
|
|
| 91 |
testStatus = 'Completed';
|
| 92 |
progress = 100;
|
| 93 |
}, MaxTestDurationSec * 1000);
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
};
|
| 95 |
const stopTest = () => {
|
| 96 |
testStatus = 'Stopped';
|
| 97 |
clearTimeout(testTimeoutHandler);
|
|
|
|
| 98 |
};
|
| 99 |
-
$effect(() => {
|
| 100 |
-
(async () => {
|
| 101 |
-
if (testStatus === 'Completed') {
|
| 102 |
-
// send analytics event
|
| 103 |
-
await sendAnalyticsData(currentBandwidth, currentLatency, serverLocation);
|
| 104 |
-
}
|
| 105 |
-
})();
|
| 106 |
-
});
|
| 107 |
-
//counter(callback);
|
| 108 |
-
//bandwidthTest(bandwidthCallback, latencyCallback);
|
| 109 |
|
| 110 |
let canvas: HTMLCanvasElement;
|
| 111 |
|
|
@@ -231,7 +229,7 @@
|
|
| 231 |
<div class="mb-2 flex justify-between">
|
| 232 |
<span class="text-sm font-medium text-gray-700">Test Progress</span>
|
| 233 |
<span id="progress-percent" class="text-sm font-medium text-gray-700"
|
| 234 |
-
|
| 235 |
>
|
| 236 |
</div>
|
| 237 |
<div class="h-2.5 w-full rounded-full bg-gray-200">
|
|
|
|
| 77 |
};
|
| 78 |
|
| 79 |
let testTimeoutHandler = 0;
|
| 80 |
+
let earlyAnalyticsHandler = 0;
|
| 81 |
|
| 82 |
const startTest = () => {
|
| 83 |
testStatus = 'Running';
|
|
|
|
| 89 |
bandwidthTest(bandwidthCallback, latencyCallback, serverLocationCallback);
|
| 90 |
testTimeoutHandler = setTimeout(async () => {
|
| 91 |
console.log('Test timed out after', MaxTestDurationSec, 'seconds');
|
| 92 |
+
// send final analytics data even if the test is not completed (we have enough data for a good estimate)
|
| 93 |
+
await sendAnalyticsData(currentBandwidth, currentLatency, serverLocation, 1.);
|
| 94 |
testStatus = 'Completed';
|
| 95 |
progress = 100;
|
| 96 |
}, MaxTestDurationSec * 1000);
|
| 97 |
+
earlyAnalyticsHandler = setTimeout(() => {
|
| 98 |
+
// send analytics event after 5 seconds (in case user closes the tab before the test completes)
|
| 99 |
+
sendAnalyticsData(currentBandwidth, currentLatency, serverLocation, progress / 100);
|
| 100 |
+
}, 5000);
|
| 101 |
};
|
| 102 |
const stopTest = () => {
|
| 103 |
testStatus = 'Stopped';
|
| 104 |
clearTimeout(testTimeoutHandler);
|
| 105 |
+
clearTimeout(earlyAnalyticsHandler);
|
| 106 |
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
|
| 108 |
let canvas: HTMLCanvasElement;
|
| 109 |
|
|
|
|
| 229 |
<div class="mb-2 flex justify-between">
|
| 230 |
<span class="text-sm font-medium text-gray-700">Test Progress</span>
|
| 231 |
<span id="progress-percent" class="text-sm font-medium text-gray-700"
|
| 232 |
+
>{progress.toFixed(0)}%</span
|
| 233 |
>
|
| 234 |
</div>
|
| 235 |
<div class="h-2.5 w-full rounded-full bg-gray-200">
|
src/routes/analytics/+server.ts
CHANGED
|
@@ -16,12 +16,13 @@ const ddbClient = new DynamoDBClient({ region: REGION });
|
|
| 16 |
|
| 17 |
export async function POST({ request }) {
|
| 18 |
try {
|
| 19 |
-
const { bandwidth, latency, location } = await request.json();
|
| 20 |
|
| 21 |
if (
|
| 22 |
typeof bandwidth !== 'number' ||
|
| 23 |
typeof latency !== 'number' ||
|
| 24 |
-
typeof location !== 'string'
|
|
|
|
| 25 |
) {
|
| 26 |
return json({ error: 'Invalid data' }, { status: 400 });
|
| 27 |
}
|
|
@@ -35,7 +36,8 @@ export async function POST({ request }) {
|
|
| 35 |
bandwidth: { N: bandwidth.toString() },
|
| 36 |
latency: { N: latency.toString() },
|
| 37 |
location: { S: location },
|
| 38 |
-
timestamp: { S: new Date().toISOString() }
|
|
|
|
| 39 |
};
|
| 40 |
|
| 41 |
const putParams = {
|
|
@@ -45,7 +47,7 @@ export async function POST({ request }) {
|
|
| 45 |
|
| 46 |
await ddbClient.send(new PutItemCommand(putParams));
|
| 47 |
|
| 48 |
-
console.log('Received bandwidth data:', { bandwidth, latency, location });
|
| 49 |
|
| 50 |
return json({ success: true });
|
| 51 |
} catch (error) {
|
|
|
|
| 16 |
|
| 17 |
export async function POST({ request }) {
|
| 18 |
try {
|
| 19 |
+
const { bandwidth, latency, location, progress } = await request.json();
|
| 20 |
|
| 21 |
if (
|
| 22 |
typeof bandwidth !== 'number' ||
|
| 23 |
typeof latency !== 'number' ||
|
| 24 |
+
typeof location !== 'string' ||
|
| 25 |
+
typeof progress !== 'number'
|
| 26 |
) {
|
| 27 |
return json({ error: 'Invalid data' }, { status: 400 });
|
| 28 |
}
|
|
|
|
| 36 |
bandwidth: { N: bandwidth.toString() },
|
| 37 |
latency: { N: latency.toString() },
|
| 38 |
location: { S: location },
|
| 39 |
+
timestamp: { S: new Date().toISOString() },
|
| 40 |
+
progress: { N: progress.toString() }
|
| 41 |
};
|
| 42 |
|
| 43 |
const putParams = {
|
|
|
|
| 47 |
|
| 48 |
await ddbClient.send(new PutItemCommand(putParams));
|
| 49 |
|
| 50 |
+
console.log('Received bandwidth data:', { bandwidth, latency, location, progress });
|
| 51 |
|
| 52 |
return json({ success: true });
|
| 53 |
} catch (error) {
|