From 829dd06b4202abb3c4445ad7ef440fec03f3f472 Mon Sep 17 00:00:00 2001 From: Luis Pater Date: Fri, 10 Oct 2025 02:35:15 +0800 Subject: [PATCH] feat(cliproxy/auth): restructure auth candidate selection and ensure synchronization - Refactored candidate selection logic in `auth/manager.go`. - Ensured proper synchronization around `mu.RUnlock` to prevent racing conditions. --- sdk/cliproxy/auth/manager.go | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/sdk/cliproxy/auth/manager.go b/sdk/cliproxy/auth/manager.go index 92eda109..3b06beb0 100644 --- a/sdk/cliproxy/auth/manager.go +++ b/sdk/cliproxy/auth/manager.go @@ -787,27 +787,31 @@ func (m *Manager) pickNext(ctx context.Context, provider, model string, opts cli return nil, nil, &Error{Code: "executor_not_found", Message: "executor not registered"} } candidates := make([]*Auth, 0, len(m.auths)) - for _, auth := range m.auths { - if auth.Provider != provider || auth.Disabled { + for _, candidate := range m.auths { + if candidate.Provider != provider || candidate.Disabled { continue } - if _, used := tried[auth.ID]; used { + if _, used := tried[candidate.ID]; used { continue } - candidates = append(candidates, auth.Clone()) + candidates = append(candidates, candidate) } - m.mu.RUnlock() if len(candidates) == 0 { + m.mu.RUnlock() return nil, nil, &Error{Code: "auth_not_found", Message: "no auth available"} } - auth, errPick := m.selector.Pick(ctx, provider, model, opts, candidates) + selected, errPick := m.selector.Pick(ctx, provider, model, opts, candidates) if errPick != nil { + m.mu.RUnlock() return nil, nil, errPick } - if auth == nil { + if selected == nil { + m.mu.RUnlock() return nil, nil, &Error{Code: "auth_not_found", Message: "selector returned no auth"} } - return auth, executor, nil + authCopy := selected.Clone() + m.mu.RUnlock() + return authCopy, executor, nil } func (m *Manager) persist(ctx context.Context, auth *Auth) error {