History

Refine watcher delete suppression and maintenance scans

benjamin committed 7 months agov0.1.0

Commit 768ffe21 parent e509adc3 files · +60 −6Browse files

Unified · Split

3 files
  1. internal/watcher/events.go +1 −1
  2. internal/watcher/watcher_test.go +7 −0
  3. sdk/cliproxy/service.go +52 −5
internal/watcher/events.go+1−1
@@ -90,11 +90,11 @@ func (w *Watcher) handleEvent(event fsnotify.Event) { · 89 unmodified lines
9090
9191 // Handle auth directory changes incrementally (.json only)
9292 if event.Op&(fsnotify.Remove|fsnotify.Rename) != 0 {
93+ w.cancelPendingAuthWrite(normalizedName)
9394 if w.isAuthPathSuppressed(normalizedName, now) {
9495 log.Debugf("suppressing auth event for %s", filepath.Base(event.Name))
9596 return
9697 }
97− w.cancelPendingAuthWrite(normalizedName)
9898 if w.shouldDebounceRemove(normalizedName, now) {
9999 log.Debugf("debouncing remove event for %s", filepath.Base(event.Name))
100100 return
internal/watcher/watcher_test.go+7−0
@@ -1258,11 +1258,18 @@ func TestHandleEventSuppressedAuthPathSkipsKnownRemove(t *testing.T) { · 1257 unmodified lines
12581258 w.SetConfig(&config.Config{AuthDir: authDir})
12591259 w.lastAuthHashes[w.normalizeAuthPath(authFile)] = "hash"
12601260 w.SuppressAuthPath(authFile, time.Second)
1261+ w.scheduleAuthWrite(w.normalizeAuthPath(authFile), authFile)
12611262
12621263 w.handleEvent(fsnotify.Event{Name: authFile, Op: fsnotify.Remove})
12631264 if _, ok := w.lastAuthHashes[w.normalizeAuthPath(authFile)]; !ok {
12641265 t.Fatal("expected suppressed remove to leave watcher auth cache untouched")
12651266 }
1267+ w.eventMu.Lock()
1268+ pending := len(w.pendingAuthWrites)
1269+ w.eventMu.Unlock()
1270+ if pending != 0 {
1271+ t.Fatalf("expected suppressed remove to cancel pending writes, got %d", pending)
1272+ }
12661273 }
12671274
12681275 func TestFlushPendingAuthWrite_IgnoresStaleGeneration(t *testing.T) {
sdk/cliproxy/service.go+52−5
@@ -798,11 +798,27 @@ func (s *Service) rebuildAuthMaintenanceIndex(snapshot []*coreauth.Auth, authDir · 797 unmodified lines
798798 }
799799
800800 func (s *Service) rebuildAuthMaintenanceIndexLocked(snapshot []*coreauth.Auth, authDir string) {
801− s.maintenanceAuthIDsByPath = make(map[string]map[string]struct{})
802− s.maintenanceAuthPathByID = make(map[string]string)
801+ idsByPath := make(map[string]map[string]struct{})
802+ pathByID := make(map[string]string)
803803 for _, auth := range snapshot {
804− s.indexAuthMaintenanceAuthLocked(auth, authDir)
804+ if auth == nil {
805+ continue
806+ }
807+ id := strings.TrimSpace(auth.ID)
808+ if id == "" {
809+ continue
810+ }
811+ path := resolveAuthFilePath(auth, authDir)
812+ if path == "" {
813+ continue
814+ }
815+ if idsByPath[path] == nil {
816+ idsByPath[path] = make(map[string]struct{})
817+ }
818+ idsByPath[path][id] = struct{}{}
819+ pathByID[id] = path
805820 }
821+ s.replaceAuthMaintenanceIndexLocked(idsByPath, pathByID)
806822 }
807823
808824 func (s *Service) indexAuthMaintenanceAuth(auth *coreauth.Auth) {
@@ -910,6 +926,27 @@ func (s *Service) authMaintenanceIDsForPath(path, authDir string) []string { · 101 unmodified lines
910926 return out
911927 }
912928
929+func (s *Service) replaceAuthMaintenanceIndex(idsByPath map[string]map[string]struct{}, pathByID map[string]string) {
930+ if s == nil {
931+ return
932+ }
933+ s.ensureAuthMaintenanceQueue()
934+ s.maintenanceMu.Lock()
935+ defer s.maintenanceMu.Unlock()
936+ s.replaceAuthMaintenanceIndexLocked(idsByPath, pathByID)
937+}
938+
939+func (s *Service) replaceAuthMaintenanceIndexLocked(idsByPath map[string]map[string]struct{}, pathByID map[string]string) {
940+ if idsByPath == nil {
941+ idsByPath = make(map[string]map[string]struct{})
942+ }
943+ if pathByID == nil {
944+ pathByID = make(map[string]string)
945+ }
946+ s.maintenanceAuthIDsByPath = idsByPath
947+ s.maintenanceAuthPathByID = pathByID
948+}
949+
913950 func (s *Service) snapshotAuthMaintenanceConfig() (config.AuthMaintenanceConfig, string) {
914951 if s == nil {
915952 return config.AuthMaintenanceConfig{
@@ -946,8 +983,9 @@ func (s *Service) scanAuthMaintenanceCandidates(now time.Time, cfg config.AuthMa · 30 unmodified lines
946983 return nil
947984 }
948985 snapshot := s.coreManager.List()
949− s.rebuildAuthMaintenanceIndex(snapshot, authDir)
950986 grouped := make(map[string]authMaintenanceCandidate)
987+ idsByPath := make(map[string]map[string]struct{})
988+ pathByID := make(map[string]string)
951989 for _, auth := range snapshot {
952990 path := resolveAuthFilePath(auth, authDir)
953991 if path == "" {
@@ -961,7 +999,15 @@ func (s *Service) scanAuthMaintenanceCandidates(now time.Time, cfg config.AuthMa · 7 unmodified lines
961999 }
9621000 }
9631001 if auth != nil && strings.TrimSpace(auth.ID) != "" {
964− group.IDs = append(group.IDs, strings.TrimSpace(auth.ID))
1002+ id := strings.TrimSpace(auth.ID)
1003+ if idsByPath[path] == nil {
1004+ idsByPath[path] = make(map[string]struct{})
1005+ }
1006+ if _, exists := idsByPath[path][id]; !exists {
1007+ idsByPath[path][id] = struct{}{}
1008+ group.IDs = append(group.IDs, id)
1009+ }
1010+ pathByID[id] = path
9651011 }
9661012 if group.Reason == "" {
9671013 if reason, ok := authEligibleForMaintenanceDelete(auth, nil, cfg, now); ok {
@@ -970,6 +1016,7 @@ func (s *Service) scanAuthMaintenanceCandidates(now time.Time, cfg config.AuthMa · 2 unmodified lines
9701016 }
9711017 grouped[path] = group
9721018 }
1019+ s.replaceAuthMaintenanceIndex(idsByPath, pathByID)
9731020
9741021 candidates := make([]authMaintenanceCandidate, 0, len(grouped))
9751022 for _, candidate := range grouped {