package app import ( "strings" "time" ) func transportRunHealthProbe(clientID string) { id := strings.TrimSpace(clientID) if id == "" { return } transportHealthSWR.acquire() defer transportHealthSWR.release() now := time.Now().UTC() transportMu.Lock() st := loadTransportClientsState() idx := findTransportClientIndex(st.Items, id) if idx < 0 { transportMu.Unlock() transportHealthSWR.finishError(id, "client not found", now) return } prev := st.Items[idx] transportMu.Unlock() backend := selectTransportBackend(prev) probe := backend.Health(prev) backendID := backend.ID() transportMu.Lock() st = loadTransportClientsState() idx = findTransportClientIndex(st.Items, id) if idx < 0 { transportMu.Unlock() transportHealthSWR.finishError(id, "client not found", now) return } prev = st.Items[idx] next := applyTransportHealthProbeSnapshot(prev, backendID, probe, now) healthChanged := transportHealthChanged(prev, next) persist := transportShouldPersistHealthSnapshot(prev, next, now) if persist { st.Items[idx] = next if err := saveTransportClientsState(st); err != nil { transportMu.Unlock() transportHealthSWR.finishError(id, "save failed: "+err.Error(), now) return } } transportMu.Unlock() if healthChanged { events.push("transport_client_health_changed", map[string]any{ "id": id, "status": next.Status, "latency_ms": next.Health.LatencyMS, "last_error": strings.TrimSpace(next.Health.LastError), "last_check": strings.TrimSpace(next.Health.LastCheck), }) publishTransportRuntimeObservabilitySnapshotChanged( "transport_client_health_changed", []string{id}, nil, ) } if probe.OK { transportHealthSWR.finishSuccess(id, now) return } msg := strings.TrimSpace(probe.Message) if msg == "" { msg = "transport health probe failed" } transportHealthSWR.finishError(id, msg, now) }