Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request metrics improvements #8420

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open

Conversation

enahum
Copy link
Contributor

@enahum enahum commented Dec 17, 2024

Summary

More improvements on network metrics include speed, effective latency and more importantly some changes with the entry fetching endpoints.

Ticket Link

https://mattermost.atlassian.net/browse/MM-61878

Release Note

NONE

Update groupLabel to use a type definition
Include effective Latency and Average Speed in the metrics
Include parallel and sequential request counts
Copy link
Member

@isacikgoz isacikgoz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added my comments, wherever I have an idea :)

}

const urlData = Object.entries(groupData.urls);
const sumLatency = urlData.reduce((result, url) => (result + (url[1].metrics?.latency ?? 0)), 0);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we discard 0 latency from equation, ideally it should never happen though right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should never happen really, the 0 here is forced to be type safe.

const effectiveParallelLatency = Math.max(...parallelLatencies, 0);
const effectiveSequentialLatency = sequentialLatencies.reduce((sum, latency) => sum + latency, 0);

const effectiveLatency = effectiveParallelLatency + effectiveSequentialLatency;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these need to be summed or should we get the avg especially for sequential latency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as far as I'm aware, for parallel requests the latency is the maximum latency of all requests and then sequential requests do add up to get the effective latency as if you execute two sequential requests and one takes 3s and the other one 5s then you waited a total of 8s.

that is the reason why I added the avg latency overall.

const averageSpeedMbps = averageSpeedBps / 1_000_000; // Convert to Mbps

return {
averageSpeedMbps,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can use avg speed to decide whether download files or whatsoever.

performance.mark('tti', options);
}

public measureTimeToInteraction() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay, long anticipated metric is here :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but is nothing more than an output to the console at the moment.. I need to figure out where and how to include it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I create another metric on the server to collect this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rahimrahman can it be optional? I think that'll be very nice to have but haven't checked into how to include it as is a totally different metric collected in a different way and somewhere else in the code

)

* feat(MM-61865): send network info telemetry data

* unit testing

* fix latency vs effectiveLatency

* cleanup test

* fix failing tests

* fix spelling error

* fix failing test

* more cleanup
Comment on lines +115 to +179
categorizeRequests(groupLabel: RequestGroupLabel): CategorizedRequests {
const parallel: ClientResponseMetrics[] = [];
const sequential: ClientResponseMetrics[] = [];
const groupData = this.requestGroups.get(groupLabel);
if (!groupData) {
return {parallel, sequential};
}

// Sort requests by start time
const requestsMetrics = Object.entries(groupData.urls).map((e) => e[1].metrics).filter((m) => m != null);
requestsMetrics.sort((a, b) => a.startTime - b.startTime);

let lastEndTime = 0;

for (const metrics of requestsMetrics) {
if (metrics.startTime < lastEndTime) {
// Overlapping request -> Parallel
parallel.push(metrics);
} else {
// Non-overlapping request -> Sequential
sequential.push(metrics);
}

// Update the last end time
lastEndTime = Math.max(lastEndTime, metrics.endTime);
}

return {parallel, sequential};
}

calculateAverageSpeedWithCategories = (
categorizedRequests: CategorizedRequests,
elapsedTimeInSeconds: number, // Observed total elapsed time in seconds
): { averageSpeedMbps: number; effectiveLatency: number } => {
const {parallel, sequential} = categorizedRequests;

// Step 1: Calculate total data size in bits
const totalDataBits = [...parallel, ...sequential].reduce((sum, req) => sum + (req.compressedSize * 8), 0);

// Step 2: Calculate effective latency
const parallelLatencies = parallel.map((req) => req.latency);
const sequentialLatencies = sequential.map((req) => req.latency);

const effectiveParallelLatency = Math.max(...parallelLatencies, 0);
const effectiveSequentialLatency = sequentialLatencies.reduce((sum, latency) => sum + latency, 0);

const effectiveLatency = effectiveParallelLatency + effectiveSequentialLatency;

// Step 3: Calculate data transfer time
const dataTransferTime = elapsedTimeInSeconds - (effectiveLatency / 1000);

// Handle edge case: if data transfer time is zero or negative
if (dataTransferTime <= 0) {
return {averageSpeedMbps: 0, effectiveLatency: 0};
}

// Step 4: Calculate average speed
const averageSpeedBps = totalDataBits / dataTransferTime; // Speed in bps
const averageSpeedMbps = averageSpeedBps / 1_000_000; // Convert to Mbps

return {
averageSpeedMbps,
effectiveLatency,
};
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made a significant proposed improvement based on data observation. I will try to explain as much as possible in this PR: #8439.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants