diff --git a/backend/internal/service/ollama_cloud_usage_test.go b/backend/internal/service/ollama_cloud_usage_test.go index 851b30cb48..d949ce41fd 100644 --- a/backend/internal/service/ollama_cloud_usage_test.go +++ b/backend/internal/service/ollama_cloud_usage_test.go @@ -54,16 +54,19 @@ func (r *ollamaUsageTestRepo) ListOllamaCloudUsageGroupAccounts(_ context.Contex if _, match := wanted[fingerprint]; !ok || !match { continue } - clone := *account - clone.Extra = make(map[string]any, len(account.Extra)) - for key, value := range account.Extra { - clone.Extra[key] = value - } - result = append(result, clone) + result = append(result, cloneOllamaUsageTestAccount(*account)) } return result, nil } +// cloneOllamaUsageTestAccount 深拷贝共享 map,模拟真实仓储每次查询返回全新行: +// 组写在 r.mu 下改成员 map,浅拷贝会让 RunDue 过滤循环无锁读到同一 map 而竞争。 +func cloneOllamaUsageTestAccount(account Account) Account { + account.Credentials = mergeMap(nil, account.Credentials) + account.Extra = mergeMap(nil, account.Extra) + return account +} + func (r *ollamaUsageTestRepo) SaveOllamaCloudUsageSession(_ context.Context, expected *Account, ciphertext string, autoRefresh bool) error { r.mu.Lock() defer r.mu.Unlock() @@ -183,14 +186,18 @@ func applyOllamaUsageTestManagedExtra(account, source *Account) { } func (r *ollamaUsageTestRepo) ListDueOllamaCloudUsageAccounts(_ context.Context, _ time.Time, limit int) ([]Account, error) { - if len(r.due) > 0 { - return append([]Account(nil), r.due[:min(limit, len(r.due))]...), nil - } r.mu.Lock() defer r.mu.Unlock() + if len(r.due) > 0 { + out := make([]Account, 0, min(limit, len(r.due))) + for _, account := range r.due[:min(limit, len(r.due))] { + out = append(out, cloneOllamaUsageTestAccount(account)) + } + return out, nil + } out := make([]Account, 0, len(r.accounts)) for _, account := range r.accounts { - out = append(out, *account) + out = append(out, cloneOllamaUsageTestAccount(*account)) if len(out) == limit { break }