fix: improve sticky session scheduling
This commit is contained in:
@@ -449,11 +449,69 @@ func buildSchedulerMetadataAccount(account service.Account) service.Account {
|
||||
SessionWindowStart: account.SessionWindowStart,
|
||||
SessionWindowEnd: account.SessionWindowEnd,
|
||||
SessionWindowStatus: account.SessionWindowStatus,
|
||||
AccountGroups: filterSchedulerAccountGroups(account.AccountGroups),
|
||||
GroupIDs: filterSchedulerGroupIDs(account.GroupIDs, account.AccountGroups),
|
||||
Credentials: filterSchedulerCredentials(account.Credentials),
|
||||
Extra: filterSchedulerExtra(account.Extra),
|
||||
}
|
||||
}
|
||||
|
||||
func filterSchedulerAccountGroups(accountGroups []service.AccountGroup) []service.AccountGroup {
|
||||
if len(accountGroups) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
filtered := make([]service.AccountGroup, 0, len(accountGroups))
|
||||
for _, ag := range accountGroups {
|
||||
if ag.GroupID <= 0 {
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, service.AccountGroup{
|
||||
AccountID: ag.AccountID,
|
||||
GroupID: ag.GroupID,
|
||||
Priority: ag.Priority,
|
||||
CreatedAt: ag.CreatedAt,
|
||||
})
|
||||
}
|
||||
if len(filtered) == 0 {
|
||||
return nil
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func filterSchedulerGroupIDs(groupIDs []int64, accountGroups []service.AccountGroup) []int64 {
|
||||
if len(groupIDs) == 0 && len(accountGroups) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
seen := make(map[int64]struct{}, len(groupIDs)+len(accountGroups))
|
||||
filtered := make([]int64, 0, len(groupIDs)+len(accountGroups))
|
||||
for _, id := range groupIDs {
|
||||
if id <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[id]; ok {
|
||||
continue
|
||||
}
|
||||
seen[id] = struct{}{}
|
||||
filtered = append(filtered, id)
|
||||
}
|
||||
for _, ag := range accountGroups {
|
||||
if ag.GroupID <= 0 {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[ag.GroupID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[ag.GroupID] = struct{}{}
|
||||
filtered = append(filtered, ag.GroupID)
|
||||
}
|
||||
if len(filtered) == 0 {
|
||||
return nil
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
|
||||
func filterSchedulerCredentials(credentials map[string]any) map[string]any {
|
||||
if len(credentials) == 0 {
|
||||
return nil
|
||||
|
||||
@@ -56,6 +56,15 @@ func TestSchedulerCacheSnapshotUsesSlimMetadataButKeepsFullAccount(t *testing.T)
|
||||
SessionWindowStart: &now,
|
||||
SessionWindowEnd: &windowEnd,
|
||||
SessionWindowStatus: "active",
|
||||
GroupIDs: []int64{bucket.GroupID},
|
||||
AccountGroups: []service.AccountGroup{
|
||||
{
|
||||
AccountID: 101,
|
||||
GroupID: bucket.GroupID,
|
||||
Priority: 5,
|
||||
Group: &service.Group{ID: bucket.GroupID, Name: "gemini-group"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, cache.SetSnapshot(ctx, bucket, []service.Account{account}))
|
||||
@@ -79,10 +88,17 @@ func TestSchedulerCacheSnapshotUsesSlimMetadataButKeepsFullAccount(t *testing.T)
|
||||
require.Equal(t, 4, got.GetMaxSessions())
|
||||
require.Equal(t, 11, got.GetSessionIdleTimeoutMinutes())
|
||||
require.Nil(t, got.Extra["unused_large_field"])
|
||||
require.Equal(t, []int64{bucket.GroupID}, got.GroupIDs)
|
||||
require.Len(t, got.AccountGroups, 1)
|
||||
require.Equal(t, account.ID, got.AccountGroups[0].AccountID)
|
||||
require.Equal(t, bucket.GroupID, got.AccountGroups[0].GroupID)
|
||||
require.Nil(t, got.AccountGroups[0].Group)
|
||||
|
||||
full, err := cache.GetAccount(ctx, account.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, full)
|
||||
require.Equal(t, "secret-access-token", full.GetCredential("access_token"))
|
||||
require.Equal(t, strings.Repeat("x", 4096), full.GetCredential("huge_blob"))
|
||||
require.Len(t, full.AccountGroups, 1)
|
||||
require.NotNil(t, full.AccountGroups[0].Group)
|
||||
}
|
||||
|
||||
@@ -31,3 +31,43 @@ func TestBuildSchedulerMetadataAccount_KeepsOpenAIWSFlags(t *testing.T) {
|
||||
require.Equal(t, true, got.Extra["mixed_scheduling"])
|
||||
require.Nil(t, got.Extra["unused_large_field"])
|
||||
}
|
||||
|
||||
func TestBuildSchedulerMetadataAccount_KeepsSlimGroupMembership(t *testing.T) {
|
||||
account := service.Account{
|
||||
ID: 42,
|
||||
Platform: service.PlatformAnthropic,
|
||||
GroupIDs: []int64{7, 9, 7, 0},
|
||||
AccountGroups: []service.AccountGroup{
|
||||
{
|
||||
AccountID: 42,
|
||||
GroupID: 7,
|
||||
Priority: 2,
|
||||
Account: &service.Account{ID: 42, Name: "drop-from-metadata"},
|
||||
Group: &service.Group{ID: 7, Name: "drop-from-metadata"},
|
||||
},
|
||||
{
|
||||
AccountID: 42,
|
||||
GroupID: 11,
|
||||
Priority: 3,
|
||||
Group: &service.Group{ID: 11, Name: "drop-from-metadata"},
|
||||
},
|
||||
{
|
||||
AccountID: 42,
|
||||
GroupID: 0,
|
||||
Priority: 4,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
got := buildSchedulerMetadataAccount(account)
|
||||
|
||||
require.Equal(t, []int64{7, 9, 11}, got.GroupIDs)
|
||||
require.Len(t, got.AccountGroups, 2)
|
||||
require.Equal(t, int64(42), got.AccountGroups[0].AccountID)
|
||||
require.Equal(t, int64(7), got.AccountGroups[0].GroupID)
|
||||
require.Equal(t, 2, got.AccountGroups[0].Priority)
|
||||
require.Nil(t, got.AccountGroups[0].Account)
|
||||
require.Nil(t, got.AccountGroups[0].Group)
|
||||
require.Equal(t, int64(11), got.AccountGroups[1].GroupID)
|
||||
require.Nil(t, got.Groups)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user