compute static method
Computes all stats in a single, high-performance pass.
Implementation
static AliceStatsData compute(List<AliceHttpCall> callList) {
int pending = 0;
int success = 0;
int redirection = 0;
int error = 0;
int bytesSent = 0;
int bytesReceived = 0;
int requestTimeSum = 0;
int completedCount = 0;
int maxRequestTime = 0;
int minRequestTime = callList.isEmpty ? 0 : 10000000;
int getCount = 0;
int postCount = 0;
int deleteCount = 0;
int putCount = 0;
int patchCount = 0;
int securedCount = 0;
int unsecuredCount = 0;
int heavyPayloadCount = 0;
final statusCodes = <int, int>{};
final slowestCalls = <AliceHttpCall>[];
final endpointMap = <String, List<AliceHttpCall>>{};
for (final call in callList) {
if (call.loading) {
pending++;
}
final response = call.response;
if (response != null) {
final status = response.status;
if (status >= 200 && status < 300) {
success++;
} else if (status >= 300 && status < 400) {
redirection++;
} else if (status >= 400 && status < 600) {
error++;
}
if (status > 0) {
statusCodes[status] = (statusCodes[status] ?? 0) + 1;
}
bytesReceived += response.size;
if (response.size > 1024 * 1024) {
heavyPayloadCount++;
}
}
final request = call.request;
if (request != null) {
bytesSent += request.size;
}
if (!call.loading) {
completedCount++;
requestTimeSum += call.duration;
maxRequestTime = math.max(maxRequestTime, call.duration);
minRequestTime = math.min(minRequestTime, call.duration);
slowestCalls.add(call);
}
final method = call.method.toUpperCase();
switch (method) {
case "GET":
getCount++;
case "POST":
postCount++;
case "DELETE":
deleteCount++;
case "PUT":
putCount++;
case "PATCH":
patchCount++;
}
if (call.secure) {
securedCount++;
} else {
unsecuredCount++;
}
// Group by method and endpoint
final key = "$method ${call.endpoint}";
(endpointMap[key] ??= []).add(call);
}
// Sort slowest calls descending
slowestCalls.sort((a, b) => b.duration.compareTo(a.duration));
// Build endpoint stats list
final endpointStats = <AliceEndpointStats>[];
for (final entry in endpointMap.entries) {
final calls = entry.value;
final first = calls.first;
int epDurationSum = 0;
int epErrorCount = 0;
int epMinDuration = calls.first.duration;
int epMaxDuration = 0;
int epTotalBytes = 0;
for (final c in calls) {
epDurationSum += c.duration;
epMaxDuration = math.max(epMaxDuration, c.duration);
epMinDuration = math.min(epMinDuration, c.duration);
if (c.error != null || ((c.response?.status ?? 0) >= 400)) {
epErrorCount++;
}
if (c.response != null) {
epTotalBytes += c.response!.size;
}
}
endpointStats.add(
AliceEndpointStats(
method: first.method,
endpoint: first.endpoint,
server: first.server,
count: calls.length,
errorCount: epErrorCount,
totalDuration: epDurationSum,
minDuration: epMinDuration,
maxDuration: epMaxDuration,
totalBytes: epTotalBytes,
calls: calls,
),
);
}
// Sort endpoints by call count descending by default
endpointStats.sort((a, b) => b.count.compareTo(a.count));
return AliceStatsData(
totalRequests: callList.length,
pendingRequests: pending,
successRequests: success,
redirectionRequests: redirection,
errorRequests: error,
bytesSent: bytesSent,
bytesReceived: bytesReceived,
avgDuration: completedCount > 0 ? requestTimeSum ~/ completedCount : 0,
minDuration: callList.isEmpty || completedCount == 0 ? 0 : minRequestTime,
maxDuration: maxRequestTime,
getCount: getCount,
postCount: postCount,
putCount: putCount,
deleteCount: deleteCount,
patchCount: patchCount,
securedCount: securedCount,
unsecuredCount: unsecuredCount,
heavyPayloadCount: heavyPayloadCount,
statusCodes: statusCodes,
slowestCalls: slowestCalls,
endpointStats: endpointStats,
);
}