77 "os"
88 "strconv"
99 "strings"
10+ "sync/atomic"
1011
1112 "gpt-load/internal/errors"
1213 "gpt-load/pkg/types"
@@ -37,7 +38,8 @@ var DefaultConstants = Constants{
3738
3839// Manager implements the ConfigManager interface
3940type Manager struct {
40- config * Config
41+ config * Config
42+ roundRobinCounter uint64
4143}
4244
4345// Config represents the application configuration
@@ -70,8 +72,8 @@ func NewManager() (types.ConfigManager, error) {
7072 MaxRetries : parseInteger (os .Getenv ("MAX_RETRIES" ), 3 ),
7173 },
7274 OpenAI : types.OpenAIConfig {
73- BaseURL : getEnvOrDefault ( "OPENAI_BASE_URL" , "https://api.openai.com" ),
74- Timeout : parseInteger (os .Getenv ("REQUEST_TIMEOUT" ), DefaultConstants .DefaultTimeout ),
75+ BaseURLs : parseArray ( os . Getenv ( "OPENAI_BASE_URL" ), [] string { "https://api.openai.com" } ),
76+ Timeout : parseInteger (os .Getenv ("REQUEST_TIMEOUT" ), DefaultConstants .DefaultTimeout ),
7577 },
7678 Auth : types.AuthConfig {
7779 Key : os .Getenv ("AUTH_KEY" ),
@@ -120,7 +122,15 @@ func (m *Manager) GetKeysConfig() types.KeysConfig {
120122
121123// GetOpenAIConfig returns OpenAI configuration
122124func (m * Manager ) GetOpenAIConfig () types.OpenAIConfig {
123- return m .config .OpenAI
125+ config := m .config .OpenAI
126+ if len (config .BaseURLs ) > 1 {
127+ // Use atomic counter for thread-safe round-robin
128+ index := atomic .AddUint64 (& m .roundRobinCounter , 1 ) - 1
129+ config .BaseURL = config .BaseURLs [index % uint64 (len (config .BaseURLs ))]
130+ } else if len (config .BaseURLs ) == 1 {
131+ config .BaseURL = config .BaseURLs [0 ]
132+ }
133+ return config
124134}
125135
126136// GetAuthConfig returns authentication configuration
@@ -168,8 +178,13 @@ func (m *Manager) Validate() error {
168178 }
169179
170180 // Validate upstream URL format
171- if _ , err := url .Parse (m .config .OpenAI .BaseURL ); err != nil {
172- validationErrors = append (validationErrors , "invalid upstream API URL format" )
181+ if len (m .config .OpenAI .BaseURLs ) == 0 {
182+ validationErrors = append (validationErrors , "at least one upstream API URL is required" )
183+ }
184+ for _ , baseURL := range m .config .OpenAI .BaseURLs {
185+ if _ , err := url .Parse (baseURL ); err != nil {
186+ validationErrors = append (validationErrors , fmt .Sprintf ("invalid upstream API URL format: %s" , baseURL ))
187+ }
173188 }
174189
175190 // Validate performance configuration
@@ -196,7 +211,7 @@ func (m *Manager) DisplayConfig() {
196211 logrus .Infof (" Start index: %d" , m .config .Keys .StartIndex )
197212 logrus .Infof (" Blacklist threshold: %d errors" , m .config .Keys .BlacklistThreshold )
198213 logrus .Infof (" Max retries: %d" , m .config .Keys .MaxRetries )
199- logrus .Infof (" Upstream URL : %s" , m .config .OpenAI .BaseURL )
214+ logrus .Infof (" Upstream URLs : %s" , strings . Join ( m .config .OpenAI .BaseURLs , ", " ) )
200215 logrus .Infof (" Request timeout: %dms" , m .config .OpenAI .Timeout )
201216
202217 authStatus := "disabled"
0 commit comments