fix(auth): new OAuth accounts invisible to scheduler after dynamic registration
When new OAuth auth files are added while the service is running, `applyCoreAuthAddOrUpdate` calls `coreManager.Register()` (which upserts into the scheduler) BEFORE `registerModelsForAuth()`. At upsert time, `buildScheduledAuthMeta` snapshots `supportedModelSetForAuth` from the global model registry — but models haven't been registered yet, so the set is empty. With an empty `supportedModelSet`, `supportsModel()` always returns false and the new auth is never added to any model shard. Additionally, when all existing accounts are in cooldown, the scheduler returns `modelCooldownError`, but `shouldRetrySchedulerPick` only handles `*Error` types — so the `syncScheduler` safety-net rebuild never triggers and the new accounts remain invisible. Fix: 1. Add `RefreshSchedulerEntry()` to re-upsert a single auth after its models are registered, rebuilding `supportedModelSet` from the now-populated registry. 2. Call it from `applyCoreAuthAddOrUpdate` after `registerModelsForAuth`. 3. Make `shouldRetrySchedulerPick` also match `*modelCooldownError` so the full scheduler rebuild triggers when all credentials are cooling down — catching any similar stale-snapshot edge cases.
This commit is contained in:
@@ -213,6 +213,26 @@ func (m *Manager) syncScheduler() {
|
|||||||
m.syncSchedulerFromSnapshot(m.snapshotAuths())
|
m.syncSchedulerFromSnapshot(m.snapshotAuths())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RefreshSchedulerEntry re-upserts a single auth into the scheduler so that its
|
||||||
|
// supportedModelSet is rebuilt from the current global model registry state.
|
||||||
|
// This must be called after models have been registered for a newly added auth,
|
||||||
|
// because the initial scheduler.upsertAuth during Register/Update runs before
|
||||||
|
// registerModelsForAuth and therefore snapshots an empty model set.
|
||||||
|
func (m *Manager) RefreshSchedulerEntry(authID string) {
|
||||||
|
if m == nil || m.scheduler == nil || authID == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
m.mu.RLock()
|
||||||
|
auth, ok := m.auths[authID]
|
||||||
|
if !ok || auth == nil {
|
||||||
|
m.mu.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
snapshot := auth.Clone()
|
||||||
|
m.mu.RUnlock()
|
||||||
|
m.scheduler.upsertAuth(snapshot)
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Manager) SetSelector(selector Selector) {
|
func (m *Manager) SetSelector(selector Selector) {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return
|
return
|
||||||
@@ -2038,6 +2058,10 @@ func shouldRetrySchedulerPick(err error) bool {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
var cooldownErr *modelCooldownError
|
||||||
|
if errors.As(err, &cooldownErr) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
var authErr *Error
|
var authErr *Error
|
||||||
if !errors.As(err, &authErr) || authErr == nil {
|
if !errors.As(err, &authErr) || authErr == nil {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -312,6 +312,12 @@ func (s *Service) applyCoreAuthAddOrUpdate(ctx context.Context, auth *coreauth.A
|
|||||||
// This operation may block on network calls, but the auth configuration
|
// This operation may block on network calls, but the auth configuration
|
||||||
// is already effective at this point.
|
// is already effective at this point.
|
||||||
s.registerModelsForAuth(auth)
|
s.registerModelsForAuth(auth)
|
||||||
|
|
||||||
|
// Refresh the scheduler entry so that the auth's supportedModelSet is rebuilt
|
||||||
|
// from the now-populated global model registry. Without this, newly added auths
|
||||||
|
// have an empty supportedModelSet (because Register/Update upserts into the
|
||||||
|
// scheduler before registerModelsForAuth runs) and are invisible to the scheduler.
|
||||||
|
s.coreManager.RefreshSchedulerEntry(auth.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) applyCoreAuthRemoval(ctx context.Context, id string) {
|
func (s *Service) applyCoreAuthRemoval(ctx context.Context, id string) {
|
||||||
|
|||||||
Reference in New Issue
Block a user