Merge pull request #2999 from Pluviobyte/codex/sub2api-scheduler-snapshot-sync

fix: sync scheduler snapshots after account state updates
This commit is contained in:
Wesley Liddick
2026-06-06 14:27:31 +08:00
committed by GitHub
2 changed files with 40 additions and 0 deletions
@@ -1141,6 +1141,7 @@ func (r *accountRepository) SetOverloaded(ctx context.Context, id int64, until t
if err := enqueueSchedulerOutbox(ctx, r.sql, service.SchedulerOutboxEventAccountChanged, &id, nil, nil); err != nil {
logger.LegacyPrintf("repository.account", "[SchedulerOutbox] enqueue overload failed: account=%d err=%v", id, err)
}
r.syncSchedulerAccountSnapshot(ctx, id)
return nil
}
@@ -1179,6 +1180,7 @@ func (r *accountRepository) ClearTempUnschedulable(ctx context.Context, id int64
if err := enqueueSchedulerOutbox(ctx, r.sql, service.SchedulerOutboxEventAccountChanged, &id, nil, nil); err != nil {
logger.LegacyPrintf("repository.account", "[SchedulerOutbox] enqueue clear temp unschedulable failed: account=%d err=%v", id, err)
}
r.syncSchedulerAccountSnapshot(ctx, id)
return nil
}
@@ -1244,6 +1246,7 @@ func (r *accountRepository) ClearModelRateLimits(ctx context.Context, id int64)
if err := enqueueSchedulerOutbox(ctx, r.sql, service.SchedulerOutboxEventAccountChanged, &id, nil, nil); err != nil {
logger.LegacyPrintf("repository.account", "[SchedulerOutbox] enqueue clear model rate limit failed: account=%d err=%v", id, err)
}
r.syncSchedulerAccountSnapshot(ctx, id)
return nil
}
@@ -670,6 +670,8 @@ func (s *AccountRepoSuite) TestBulkUpdate_SyncSchedulerSnapshotOnDisabled() {
func (s *AccountRepoSuite) TestSetOverloaded() {
account := mustCreateAccount(s.T(), s.client, &service.Account{Name: "acc-over"})
until := time.Date(2025, 6, 15, 12, 0, 0, 0, time.UTC)
cacheRecorder := &schedulerCacheRecorder{}
s.repo.schedulerCache = cacheRecorder
s.Require().NoError(s.repo.SetOverloaded(s.ctx, account.ID, until))
@@ -677,6 +679,10 @@ func (s *AccountRepoSuite) TestSetOverloaded() {
s.Require().NoError(err)
s.Require().NotNil(got.OverloadUntil)
s.Require().WithinDuration(until, *got.OverloadUntil, time.Second)
s.Require().Len(cacheRecorder.setAccounts, 1)
s.Require().Equal(account.ID, cacheRecorder.setAccounts[0].ID)
s.Require().NotNil(cacheRecorder.setAccounts[0].OverloadUntil)
s.Require().WithinDuration(until, *cacheRecorder.setAccounts[0].OverloadUntil, time.Second)
}
func (s *AccountRepoSuite) TestSetRateLimited() {
@@ -732,11 +738,42 @@ func (s *AccountRepoSuite) TestTempUnschedulableFieldsLoadedByGetByIDAndGetByIDs
s.Require().WithinDuration(until, *gotByIDs[1].TempUnschedulableUntil, time.Second)
s.Require().Equal(reason, gotByIDs[1].TempUnschedulableReason)
cacheRecorder := &schedulerCacheRecorder{}
s.repo.schedulerCache = cacheRecorder
s.Require().NoError(s.repo.ClearTempUnschedulable(s.ctx, acc1.ID))
cleared, err := s.repo.GetByID(s.ctx, acc1.ID)
s.Require().NoError(err)
s.Require().Nil(cleared.TempUnschedulableUntil)
s.Require().Equal("", cleared.TempUnschedulableReason)
s.Require().Len(cacheRecorder.setAccounts, 1)
s.Require().Equal(acc1.ID, cacheRecorder.setAccounts[0].ID)
s.Require().Nil(cacheRecorder.setAccounts[0].TempUnschedulableUntil)
s.Require().Equal("", cacheRecorder.setAccounts[0].TempUnschedulableReason)
}
func (s *AccountRepoSuite) TestClearModelRateLimits_SyncsSchedulerSnapshot() {
account := mustCreateAccount(s.T(), s.client, &service.Account{
Name: "acc-clear-model-rate",
Extra: map[string]any{
"model_rate_limits": map[string]any{
"claude-sonnet-4-5": map[string]any{
"rate_limit_reset_at": "2026-06-03T10:00:00Z",
},
},
},
})
cacheRecorder := &schedulerCacheRecorder{}
s.repo.schedulerCache = cacheRecorder
s.Require().NoError(s.repo.ClearModelRateLimits(s.ctx, account.ID))
got, err := s.repo.GetByID(s.ctx, account.ID)
s.Require().NoError(err)
s.Require().NotContains(got.Extra, "model_rate_limits")
s.Require().Len(cacheRecorder.setAccounts, 1)
s.Require().Equal(account.ID, cacheRecorder.setAccounts[0].ID)
s.Require().NotContains(cacheRecorder.setAccounts[0].Extra, "model_rate_limits")
}
// --- UpdateLastUsed ---