package app import ( "strings" "time" ) func (r *transportHealthRefresher) syncKnownClients(items []TransportClient) { r.mu.Lock() defer r.mu.Unlock() known := make(map[string]struct{}, len(items)) for _, it := range items { id := strings.TrimSpace(it.ID) if id == "" { continue } known[id] = struct{}{} entry := r.entries[id] if entry == nil { entry = &transportHealthRefreshEntry{ swr: newRefreshCoordinator( transportHealthFreshTTL, transportHealthBackoffMin, transportHealthBackoffMax, ), } r.entries[id] = entry } if ts, ok := parseTransportHealthLastCheck(it); ok { entry.swr.setUpdatedAt(ts) } } for id := range r.entries { if _, ok := known[id]; !ok { delete(r.entries, id) } } } func (r *transportHealthRefresher) begin(item TransportClient, force bool, now time.Time) bool { id := strings.TrimSpace(item.ID) if id == "" { return false } r.mu.Lock() defer r.mu.Unlock() entry := r.entries[id] if entry == nil { entry = &transportHealthRefreshEntry{ swr: newRefreshCoordinator( transportHealthFreshTTL, transportHealthBackoffMin, transportHealthBackoffMax, ), } r.entries[id] = entry } if ts, ok := parseTransportHealthLastCheck(item); ok { entry.swr.setUpdatedAt(ts) } hasData := strings.TrimSpace(item.Health.LastCheck) != "" return entry.swr.beginRefresh(now, force, hasData) } func (r *transportHealthRefresher) finishSuccess(id string, now time.Time) { id = strings.TrimSpace(id) if id == "" { return } r.mu.Lock() defer r.mu.Unlock() entry := r.entries[id] if entry == nil { return } entry.swr.finishSuccess(now) } func (r *transportHealthRefresher) finishError(id, msg string, now time.Time) { id = strings.TrimSpace(id) if id == "" { return } r.mu.Lock() defer r.mu.Unlock() entry := r.entries[id] if entry == nil { return } entry.swr.finishError(msg, now) } func (r *transportHealthRefresher) acquire() { r.sem <- struct{}{} } func (r *transportHealthRefresher) release() { select { case <-r.sem: default: } } func parseTransportHealthLastCheck(item TransportClient) (time.Time, bool) { ts := strings.TrimSpace(item.Health.LastCheck) if ts == "" { return time.Time{}, false } t, err := time.Parse(time.RFC3339, ts) if err != nil { return time.Time{}, false } return t, true }