From 6e88380fea63a0dd0a0c79cde6eaedc172d5daaf Mon Sep 17 00:00:00 2001 From: Michael DiLeo Date: Thu, 6 Aug 2026 13:40:07 -0500 Subject: [PATCH] add the stats endpoint --- dotnet/SafelyYou/Program.cs | 18 +++++++++++++++++- dotnet/SafelyYou/UploadTimes.cs | 6 ++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/dotnet/SafelyYou/Program.cs b/dotnet/SafelyYou/Program.cs index 831578c..228779f 100644 --- a/dotnet/SafelyYou/Program.cs +++ b/dotnet/SafelyYou/Program.cs @@ -69,8 +69,24 @@ app.MapPost("/devices/{deviceId}/stats", (string deviceId, UploadStatsRequest re return Results.NoContent(); // not sure where the 500 would go here beyond doing a try/catch -}); +}); +app.MapGet("/devices/{deviceId}/stats", (string deviceId, KnownDevices knownDevices, HeartBeatHistories histories, UploadTimes uploadTimes) => +{ + var device = new DeviceId(deviceId); + if (!knownDevices.Contains(device)) + { + return Results.NotFound(new NotFoundResponse($"Device ID {deviceId} not found")); + } + + var averageUploadTimeNanos = uploadTimes.AverageUploadTimeNanoseconds(device); + var timeSpanText = TimeSpan.FromTicks((long)(averageUploadTimeNanos / 100)).ToString(@"m\ms\s"); // loses accuracy on the Go nanos for this text conversion + var uptime = histories.Uptime(device); + + return Results.Ok(new GetDeviceStatsResponse(timeSpanText, uptime)); + + // no 500 here +}); app.Run(); diff --git a/dotnet/SafelyYou/UploadTimes.cs b/dotnet/SafelyYou/UploadTimes.cs index a89e500..04599f8 100644 --- a/dotnet/SafelyYou/UploadTimes.cs +++ b/dotnet/SafelyYou/UploadTimes.cs @@ -16,4 +16,10 @@ public sealed class UploadTimes _uploadHistories[deviceId] = (history.TotalUploadTime + uploadTimeNanos, history.UploadCounts + 1); } + + public BigInteger AverageUploadTimeNanoseconds(DeviceId deviceId) + { + if (!_uploadHistories.TryGetValue(deviceId, out var history)) return BigInteger.Zero; + return history.TotalUploadTime / history.UploadCounts; + } } \ No newline at end of file