refactor(watcher): dedupe auth map conversion in incremental flow
This commit is contained in:
@@ -101,14 +101,7 @@ func (w *Watcher) reloadClients(rescanAuth bool, affectedOAuthProviders []string
|
|||||||
IDGenerator: synthesizer.NewStableIDGenerator(),
|
IDGenerator: synthesizer.NewStableIDGenerator(),
|
||||||
}
|
}
|
||||||
if generated := synthesizer.SynthesizeAuthFile(ctx, path, data); len(generated) > 0 {
|
if generated := synthesizer.SynthesizeAuthFile(ctx, path, data); len(generated) > 0 {
|
||||||
pathAuths := make(map[string]*coreauth.Auth, len(generated))
|
if pathAuths := authSliceToMap(generated); len(pathAuths) > 0 {
|
||||||
for _, a := range generated {
|
|
||||||
if a == nil || strings.TrimSpace(a.ID) == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pathAuths[a.ID] = a
|
|
||||||
}
|
|
||||||
if len(pathAuths) > 0 {
|
|
||||||
w.fileAuthsByPath[normalizedPath] = pathAuths
|
w.fileAuthsByPath[normalizedPath] = pathAuths
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,11 +191,9 @@ func (w *Watcher) addOrUpdateClient(path string) {
|
|||||||
}
|
}
|
||||||
w.lastAuthContents[normalized] = &newAuth
|
w.lastAuthContents[normalized] = &newAuth
|
||||||
|
|
||||||
oldByID := make(map[string]*coreauth.Auth)
|
oldByID := make(map[string]*coreauth.Auth, len(w.fileAuthsByPath[normalized]))
|
||||||
if existing := w.fileAuthsByPath[normalized]; len(existing) > 0 {
|
for id, a := range w.fileAuthsByPath[normalized] {
|
||||||
for id, a := range existing {
|
oldByID[id] = a
|
||||||
oldByID[id] = a
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build synthesized auth entries for this single file only.
|
// Build synthesized auth entries for this single file only.
|
||||||
@@ -213,13 +204,7 @@ func (w *Watcher) addOrUpdateClient(path string) {
|
|||||||
IDGenerator: synthesizer.NewStableIDGenerator(),
|
IDGenerator: synthesizer.NewStableIDGenerator(),
|
||||||
}
|
}
|
||||||
generated := synthesizer.SynthesizeAuthFile(sctx, path, data)
|
generated := synthesizer.SynthesizeAuthFile(sctx, path, data)
|
||||||
newByID := make(map[string]*coreauth.Auth)
|
newByID := authSliceToMap(generated)
|
||||||
for _, a := range generated {
|
|
||||||
if a == nil || strings.TrimSpace(a.ID) == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
newByID[a.ID] = a
|
|
||||||
}
|
|
||||||
if len(newByID) > 0 {
|
if len(newByID) > 0 {
|
||||||
w.fileAuthsByPath[normalized] = newByID
|
w.fileAuthsByPath[normalized] = newByID
|
||||||
} else {
|
} else {
|
||||||
@@ -235,11 +220,9 @@ func (w *Watcher) addOrUpdateClient(path string) {
|
|||||||
func (w *Watcher) removeClient(path string) {
|
func (w *Watcher) removeClient(path string) {
|
||||||
normalized := w.normalizeAuthPath(path)
|
normalized := w.normalizeAuthPath(path)
|
||||||
w.clientsMutex.Lock()
|
w.clientsMutex.Lock()
|
||||||
oldByID := make(map[string]*coreauth.Auth)
|
oldByID := make(map[string]*coreauth.Auth, len(w.fileAuthsByPath[normalized]))
|
||||||
if existing := w.fileAuthsByPath[normalized]; len(existing) > 0 {
|
for id, a := range w.fileAuthsByPath[normalized] {
|
||||||
for id, a := range existing {
|
oldByID[id] = a
|
||||||
oldByID[id] = a
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
delete(w.lastAuthHashes, normalized)
|
delete(w.lastAuthHashes, normalized)
|
||||||
delete(w.lastAuthContents, normalized)
|
delete(w.lastAuthContents, normalized)
|
||||||
@@ -279,6 +262,23 @@ func (w *Watcher) computePerPathUpdatesLocked(oldByID, newByID map[string]*corea
|
|||||||
return updates
|
return updates
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func authSliceToMap(auths []*coreauth.Auth) map[string]*coreauth.Auth {
|
||||||
|
if len(auths) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
byID := make(map[string]*coreauth.Auth, len(auths))
|
||||||
|
for _, a := range auths {
|
||||||
|
if a == nil || strings.TrimSpace(a.ID) == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
byID[a.ID] = a
|
||||||
|
}
|
||||||
|
if len(byID) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return byID
|
||||||
|
}
|
||||||
|
|
||||||
func (w *Watcher) loadFileClients(cfg *config.Config) int {
|
func (w *Watcher) loadFileClients(cfg *config.Config) int {
|
||||||
authFileCount := 0
|
authFileCount := 0
|
||||||
successfulAuthCount := 0
|
successfulAuthCount := 0
|
||||||
|
|||||||
@@ -472,6 +472,74 @@ func TestAuthFileEventsDoNotInvokeSnapshotCoreAuths(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAuthSliceToMap(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
valid1 := &coreauth.Auth{ID: "a"}
|
||||||
|
valid2 := &coreauth.Auth{ID: "b"}
|
||||||
|
dupOld := &coreauth.Auth{ID: "dup", Label: "old"}
|
||||||
|
dupNew := &coreauth.Auth{ID: "dup", Label: "new"}
|
||||||
|
empty := &coreauth.Auth{ID: " "}
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
in []*coreauth.Auth
|
||||||
|
want map[string]*coreauth.Auth
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil input",
|
||||||
|
in: nil,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty input",
|
||||||
|
in: []*coreauth.Auth{},
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "filters invalid auths",
|
||||||
|
in: []*coreauth.Auth{nil, empty},
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "keeps valid auths",
|
||||||
|
in: []*coreauth.Auth{valid1, nil, valid2},
|
||||||
|
want: map[string]*coreauth.Auth{"a": valid1, "b": valid2},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "last duplicate wins",
|
||||||
|
in: []*coreauth.Auth{dupOld, dupNew},
|
||||||
|
want: map[string]*coreauth.Auth{"dup": dupNew},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
got := authSliceToMap(tc.in)
|
||||||
|
if len(tc.want) == 0 {
|
||||||
|
if got != nil {
|
||||||
|
t.Fatalf("expected nil map, got %#v", got)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(got) != len(tc.want) {
|
||||||
|
t.Fatalf("unexpected map length: got %d, want %d", len(got), len(tc.want))
|
||||||
|
}
|
||||||
|
for id, wantAuth := range tc.want {
|
||||||
|
gotAuth, ok := got[id]
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("missing id %q in result map", id)
|
||||||
|
}
|
||||||
|
if !authEqual(gotAuth, wantAuth) {
|
||||||
|
t.Fatalf("unexpected auth for id %q: got %#v, want %#v", id, gotAuth, wantAuth)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestShouldDebounceRemove(t *testing.T) {
|
func TestShouldDebounceRemove(t *testing.T) {
|
||||||
w := &Watcher{}
|
w := &Watcher{}
|
||||||
path := filepath.Clean("test.json")
|
path := filepath.Clean("test.json")
|
||||||
|
|||||||
Reference in New Issue
Block a user