From 3c4eba87c83ba4cac56d10d541a0591b04094ea8 Mon Sep 17 00:00:00 2001 From: tajniak81 <13187254+tajniak81@users.noreply.github.com> Date: Fri, 21 Aug 2026 10:05:44 +0200 Subject: [PATCH] Status: latency the panel can actually show MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PocketBase and the Web App share a Docker network and answer a health probe in well under a millisecond. Milliseconds() truncated that to 0, and omitempty on an int64 dropped the zero from the JSON, so the panel saw no latencyMs at all and rendered an em dash. Latency is now a *float64 rounded to one decimal, computed from Microseconds(). The pointer keeps an absent measurement — the API Server row, which probes nothing — distinct from a genuinely fast one. pbProbe follows suit, since it copies straight off svcHealth. Co-Authored-By: Claude Opus 5 --- API Server/internal/api/settings.go | 10 +++++----- API Server/internal/api/status.go | 16 +++++++++++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/API Server/internal/api/settings.go b/API Server/internal/api/settings.go index ebe7469..fa2e8b1 100644 --- a/API Server/internal/api/settings.go +++ b/API Server/internal/api/settings.go @@ -16,11 +16,11 @@ import ( // URL answers its health check and whether the service-account credentials // authenticate as a superuser. type pbProbe struct { - Reachable bool `json:"reachable"` - HTTPStatus int `json:"httpStatus,omitempty"` - LatencyMs int64 `json:"latencyMs,omitempty"` - Superuser bool `json:"superuser"` - Detail string `json:"detail,omitempty"` + Reachable bool `json:"reachable"` + HTTPStatus int `json:"httpStatus,omitempty"` + LatencyMs *float64 `json:"latencyMs,omitempty"` + Superuser bool `json:"superuser"` + Detail string `json:"detail,omitempty"` } // pbConfigView is the PocketBase-connection shape returned to the panel. The diff --git a/API Server/internal/api/status.go b/API Server/internal/api/status.go index 01b5d49..177b21e 100644 --- a/API Server/internal/api/status.go +++ b/API Server/internal/api/status.go @@ -3,6 +3,7 @@ package api import ( "context" "io" + "math" "net/http" "sync" "time" @@ -11,10 +12,19 @@ import ( // svcHealth is the health of one upstream service, as shown on the panel. type svcHealth struct { Status string `json:"status"` // "ok" | "down" - LatencyMs int64 `json:"latencyMs,omitempty"` HTTPStatus int `json:"httpStatus,omitempty"` URL string `json:"url,omitempty"` - Error string `json:"error,omitempty"` + // Fractional, and a pointer so an absent measurement (this process) stays + // distinguishable from a genuinely fast one: neighbours sharing a Docker + // network answer in well under a millisecond. + LatencyMs *float64 `json:"latencyMs,omitempty"` + Error string `json:"error,omitempty"` +} + +// latencyMs is elapsed time in milliseconds, kept to one decimal. +func latencyMs(d time.Duration) *float64 { + ms := math.Round(float64(d.Microseconds())/100) / 10 + return &ms } // healthClient is a short-timeout client for probing upstreams so a hung @@ -29,7 +39,7 @@ func probe(ctx context.Context, url string) svcHealth { return svcHealth{Status: "down", URL: url, Error: err.Error()} } resp, err := healthClient.Do(req) - lat := time.Since(start).Milliseconds() + lat := latencyMs(time.Since(start)) if err != nil { return svcHealth{Status: "down", URL: url, LatencyMs: lat, Error: err.Error()} }