package app import ( "strings" "time" ) func (s *egressIdentityService) snapshot(target egressScopeTarget, now time.Time) EgressIdentity { s.mu.Lock() defer s.mu.Unlock() entry := s.ensureEntryLocked(target) return s.entrySnapshotLocked(entry, target, now) } func (s *egressIdentityService) ensureEntryLocked(target egressScopeTarget) *egressIdentityEntry { entry := s.entries[target.Scope] if entry != nil { if entry.item.Scope == "" { entry.item.Scope = target.Scope } if entry.item.Source == "" { entry.item.Source = target.Source } if entry.item.SourceID == "" { entry.item.SourceID = target.SourceID } return entry } entry = &egressIdentityEntry{ item: EgressIdentity{ Scope: target.Scope, Source: target.Source, SourceID: target.SourceID, }, swr: newRefreshCoordinator( egressIdentityFreshTTL, egressIdentityBackoffMin, egressIdentityBackoffMax, ), } s.entries[target.Scope] = entry return entry } func (s *egressIdentityService) entrySnapshotLocked( entry *egressIdentityEntry, target egressScopeTarget, now time.Time, ) EgressIdentity { item := entry.item if item.Scope == "" { item.Scope = target.Scope } if item.Source == "" { item.Source = target.Source } if item.SourceID == "" { item.SourceID = target.SourceID } meta := entry.swr.snapshot(now) item.UpdatedAt = meta.UpdatedAt item.Stale = meta.Stale item.RefreshInProgress = meta.RefreshInProgress item.LastError = strings.TrimSpace(meta.LastError) item.NextRetryAt = meta.NextRetryAt return item } func (s *egressIdentityService) acquire() { s.sem <- struct{}{} } func (s *egressIdentityService) release() { select { case <-s.sem: default: } }