Skip to content

Commit 8468e97

Browse files
committed
move redis cmab config into existing config
1 parent 1f16923 commit 8468e97

5 files changed

Lines changed: 119 additions & 122 deletions

File tree

cmd/optimizely/main.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -110,59 +110,59 @@ func loadConfig(v *viper.Viper) *config.AgentConfig {
110110
}
111111

112112
// Handle CMAB configuration using the same approach as UserProfileService
113-
// Check for complete CMAB configuration first
114-
if cmab := v.GetStringMap("cmab"); len(cmab) > 0 {
113+
// Check for complete CMAB configuration first (now under client.cmab)
114+
if cmab := v.GetStringMap("client.cmab"); len(cmab) > 0 {
115115
if timeout, ok := cmab["requestTimeout"].(string); ok {
116116
if duration, err := time.ParseDuration(timeout); err == nil {
117-
conf.CMAB.RequestTimeout = duration
117+
conf.Client.CMAB.RequestTimeout = duration
118118
}
119119
}
120120
if cache, ok := cmab["cache"].(map[string]interface{}); ok {
121-
conf.CMAB.Cache = cache
121+
conf.Client.CMAB.Cache = cache
122122
}
123123
if retryConfig, ok := cmab["retryConfig"].(map[string]interface{}); ok {
124124
if maxRetries, ok := retryConfig["maxRetries"].(float64); ok {
125-
conf.CMAB.RetryConfig.MaxRetries = int(maxRetries)
125+
conf.Client.CMAB.RetryConfig.MaxRetries = int(maxRetries)
126126
}
127127
if initialBackoff, ok := retryConfig["initialBackoff"].(string); ok {
128128
if duration, err := time.ParseDuration(initialBackoff); err == nil {
129-
conf.CMAB.RetryConfig.InitialBackoff = duration
129+
conf.Client.CMAB.RetryConfig.InitialBackoff = duration
130130
}
131131
}
132132
if maxBackoff, ok := retryConfig["maxBackoff"].(string); ok {
133133
if duration, err := time.ParseDuration(maxBackoff); err == nil {
134-
conf.CMAB.RetryConfig.MaxBackoff = duration
134+
conf.Client.CMAB.RetryConfig.MaxBackoff = duration
135135
}
136136
}
137137
if backoffMultiplier, ok := retryConfig["backoffMultiplier"].(float64); ok {
138-
conf.CMAB.RetryConfig.BackoffMultiplier = backoffMultiplier
138+
conf.Client.CMAB.RetryConfig.BackoffMultiplier = backoffMultiplier
139139
}
140140
}
141141
}
142142

143143
// Check for individual map sections
144-
if cmabCache := v.GetStringMap("cmab.cache"); len(cmabCache) > 0 {
145-
conf.CMAB.Cache = cmabCache
144+
if cmabCache := v.GetStringMap("client.cmab.cache"); len(cmabCache) > 0 {
145+
conf.Client.CMAB.Cache = cmabCache
146146
}
147147

148-
if cmabRetryConfig := v.GetStringMap("cmab.retryConfig"); len(cmabRetryConfig) > 0 {
148+
if cmabRetryConfig := v.GetStringMap("client.cmab.retryConfig"); len(cmabRetryConfig) > 0 {
149149
if maxRetries, ok := cmabRetryConfig["maxRetries"].(int); ok {
150-
conf.CMAB.RetryConfig.MaxRetries = maxRetries
150+
conf.Client.CMAB.RetryConfig.MaxRetries = maxRetries
151151
} else if maxRetries, ok := cmabRetryConfig["maxRetries"].(float64); ok {
152-
conf.CMAB.RetryConfig.MaxRetries = int(maxRetries)
152+
conf.Client.CMAB.RetryConfig.MaxRetries = int(maxRetries)
153153
}
154154
if initialBackoff, ok := cmabRetryConfig["initialBackoff"].(string); ok {
155155
if duration, err := time.ParseDuration(initialBackoff); err == nil {
156-
conf.CMAB.RetryConfig.InitialBackoff = duration
156+
conf.Client.CMAB.RetryConfig.InitialBackoff = duration
157157
}
158158
}
159159
if maxBackoff, ok := cmabRetryConfig["maxBackoff"].(string); ok {
160160
if duration, err := time.ParseDuration(maxBackoff); err == nil {
161-
conf.CMAB.RetryConfig.MaxBackoff = duration
161+
conf.Client.CMAB.RetryConfig.MaxBackoff = duration
162162
}
163163
}
164164
if backoffMultiplier, ok := cmabRetryConfig["backoffMultiplier"].(float64); ok {
165-
conf.CMAB.RetryConfig.BackoffMultiplier = backoffMultiplier
165+
conf.Client.CMAB.RetryConfig.BackoffMultiplier = backoffMultiplier
166166
}
167167
}
168168

cmd/optimizely/main_test.go

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func assertCMAB(t *testing.T, cmab config.CMABConfig) {
213213
}
214214

215215
func TestCMABEnvDebug(t *testing.T) {
216-
_ = os.Setenv("OPTIMIZELY_CMAB", `{
216+
_ = os.Setenv("OPTIMIZELY_CLIENT_CMAB", `{
217217
"requestTimeout": "15s",
218218
"cache": {
219219
"default": "redis",
@@ -245,72 +245,72 @@ func TestCMABEnvDebug(t *testing.T) {
245245

246246
// Debug: Print the parsed config
247247
fmt.Println("Parsed CMAB config from JSON env var:")
248-
fmt.Printf(" RequestTimeout: %v\n", conf.CMAB.RequestTimeout)
249-
fmt.Printf(" Cache: %+v\n", conf.CMAB.Cache)
250-
fmt.Printf(" RetryConfig: %+v\n", conf.CMAB.RetryConfig)
248+
fmt.Printf(" RequestTimeout: %v\n", conf.Client.CMAB.RequestTimeout)
249+
fmt.Printf(" Cache: %+v\n", conf.Client.CMAB.Cache)
250+
fmt.Printf(" RetryConfig: %+v\n", conf.Client.CMAB.RetryConfig)
251251

252252
// Call assertCMAB
253-
assertCMAB(t, conf.CMAB)
253+
assertCMAB(t, conf.Client.CMAB)
254254
}
255255

256256
func TestCMABPartialConfig(t *testing.T) {
257257
// Clean any existing environment variables
258-
os.Unsetenv("OPTIMIZELY_CMAB")
259-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE")
260-
os.Unsetenv("OPTIMIZELY_CMAB_RETRYCONFIG")
258+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB")
259+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE")
260+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_RETRYCONFIG")
261261

262262
// Set partial configuration through CMAB_CACHE and CMAB_RETRYCONFIG
263263
// Note: Cache is now a service-based map config
264-
_ = os.Setenv("OPTIMIZELY_CMAB_CACHE", `{"default": "redis", "services": {"redis": {"host": "localhost:6379", "database": 0}}}`)
265-
_ = os.Setenv("OPTIMIZELY_CMAB_RETRYCONFIG", `{"maxRetries": 10}`)
264+
_ = os.Setenv("OPTIMIZELY_CLIENT_CMAB_CACHE", `{"default": "redis", "services": {"redis": {"host": "localhost:6379", "database": 0}}}`)
265+
_ = os.Setenv("OPTIMIZELY_CLIENT_CMAB_RETRYCONFIG", `{"maxRetries": 10}`)
266266

267267
// Load config
268268
v := viper.New()
269269
assert.NoError(t, initConfig(v))
270270
conf := loadConfig(v)
271271

272272
// Cache assertions (cache is now map[string]interface{})
273-
assert.NotNil(t, conf.CMAB.Cache)
274-
if defaultCache, ok := conf.CMAB.Cache["default"].(string); ok {
273+
assert.NotNil(t, conf.Client.CMAB.Cache)
274+
if defaultCache, ok := conf.Client.CMAB.Cache["default"].(string); ok {
275275
assert.Equal(t, "redis", defaultCache)
276276
}
277277

278278
// RetryConfig assertions
279-
assert.Equal(t, 10, conf.CMAB.RetryConfig.MaxRetries)
279+
assert.Equal(t, 10, conf.Client.CMAB.RetryConfig.MaxRetries)
280280

281281
// Clean up
282-
os.Unsetenv("OPTIMIZELY_CMAB")
283-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE")
284-
os.Unsetenv("OPTIMIZELY_CMAB_RETRYCONFIG")
282+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB")
283+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE")
284+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_RETRYCONFIG")
285285
}
286286

287287
func TestCMABRetryConfigAllFields(t *testing.T) {
288288
// Clean any existing environment variables
289-
os.Unsetenv("OPTIMIZELY_CMAB")
290-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE")
291-
os.Unsetenv("OPTIMIZELY_CMAB_RETRYCONFIG")
289+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB")
290+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE")
291+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_RETRYCONFIG")
292292

293293
// Set all retry config fields via CMAB_RETRYCONFIG to cover lines 154-165
294-
_ = os.Setenv("OPTIMIZELY_CMAB_RETRYCONFIG", `{
294+
_ = os.Setenv("OPTIMIZELY_CLIENT_CMAB_RETRYCONFIG", `{
295295
"maxRetries": 5,
296296
"initialBackoff": "500ms",
297297
"maxBackoff": "45s",
298298
"backoffMultiplier": 2.5
299299
}`)
300300

301301
defer func() {
302-
os.Unsetenv("OPTIMIZELY_CMAB_RETRYCONFIG")
302+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_RETRYCONFIG")
303303
}()
304304

305305
v := viper.New()
306306
assert.NoError(t, initConfig(v))
307307
conf := loadConfig(v)
308308

309309
// Verify all retry config fields were parsed correctly
310-
assert.Equal(t, 5, conf.CMAB.RetryConfig.MaxRetries)
311-
assert.Equal(t, 500*time.Millisecond, conf.CMAB.RetryConfig.InitialBackoff)
312-
assert.Equal(t, 45*time.Second, conf.CMAB.RetryConfig.MaxBackoff)
313-
assert.Equal(t, 2.5, conf.CMAB.RetryConfig.BackoffMultiplier)
310+
assert.Equal(t, 5, conf.Client.CMAB.RetryConfig.MaxRetries)
311+
assert.Equal(t, 500*time.Millisecond, conf.Client.CMAB.RetryConfig.InitialBackoff)
312+
assert.Equal(t, 45*time.Second, conf.Client.CMAB.RetryConfig.MaxBackoff)
313+
assert.Equal(t, 2.5, conf.Client.CMAB.RetryConfig.BackoffMultiplier)
314314
}
315315

316316
func TestCMABRetryConfigIntMaxRetries(t *testing.T) {
@@ -320,12 +320,12 @@ func TestCMABRetryConfigIntMaxRetries(t *testing.T) {
320320
assert.NoError(t, initConfig(v))
321321

322322
// Set via viper directly to ensure it's an int, not float64
323-
v.Set("cmab.retryConfig.maxRetries", 7)
323+
v.Set("client.cmab.retryConfig.maxRetries", 7)
324324

325325
conf := loadConfig(v)
326326

327327
// Verify maxRetries was parsed as int
328-
assert.Equal(t, 7, conf.CMAB.RetryConfig.MaxRetries)
328+
assert.Equal(t, 7, conf.Client.CMAB.RetryConfig.MaxRetries)
329329
}
330330

331331
func TestViperYaml(t *testing.T) {
@@ -542,7 +542,7 @@ func TestViperEnv(t *testing.T) {
542542
_ = os.Setenv("OPTIMIZELY_WEBHOOK_PROJECTS_20000_SDKKEYS", "xxx,yyy,zzz")
543543
_ = os.Setenv("OPTIMIZELY_WEBHOOK_PROJECTS_20000_SKIPSIGNATURECHECK", "false")
544544

545-
_ = os.Setenv("OPTIMIZELY_CMAB", `{
545+
_ = os.Setenv("OPTIMIZELY_CLIENT_CMAB", `{
546546
"requestTimeout": "15s",
547547
"cache": {
548548
"default": "redis",
@@ -577,7 +577,7 @@ func TestViperEnv(t *testing.T) {
577577
assertAPI(t, actual.API)
578578
//assertWebhook(t, actual.Webhook) // Maps don't appear to be supported
579579
assertRuntime(t, actual.Runtime)
580-
assertCMAB(t, actual.CMAB)
580+
assertCMAB(t, actual.Client.CMAB)
581581
}
582582

583583
func TestLoggingWithIncludeSdkKey(t *testing.T) {
@@ -681,27 +681,27 @@ func Test_initTracing(t *testing.T) {
681681

682682
func TestCMABComplexJSON(t *testing.T) {
683683
// Clean any existing environment variables for CMAB
684-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE_TYPE")
685-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE_SIZE")
686-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE_TTL")
687-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE_REDIS_HOST")
688-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE_REDIS_PASSWORD")
689-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE_REDIS_DATABASE")
684+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE_TYPE")
685+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE_SIZE")
686+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE_TTL")
687+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE_REDIS_HOST")
688+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE_REDIS_PASSWORD")
689+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE_REDIS_DATABASE")
690690

691691
// Set complex JSON environment variable for CMAB cache (using new service-based format)
692-
_ = os.Setenv("OPTIMIZELY_CMAB_CACHE", `{"default":"redis","services":{"redis":{"host":"localhost:6379","database":0,"timeout":"3h"}}}`)
692+
_ = os.Setenv("OPTIMIZELY_CLIENT_CMAB_CACHE", `{"default":"redis","services":{"redis":{"host":"localhost:6379","database":0,"timeout":"3h"}}}`)
693693

694694
defer func() {
695695
// Clean up
696-
os.Unsetenv("OPTIMIZELY_CMAB_CACHE")
696+
os.Unsetenv("OPTIMIZELY_CLIENT_CMAB_CACHE")
697697
}()
698698

699699
v := viper.New()
700700
assert.NoError(t, initConfig(v))
701701
actual := loadConfig(v)
702702

703703
// Test cache settings from JSON environment variable (cache is now map[string]interface{})
704-
cache := actual.CMAB.Cache
704+
cache := actual.Client.CMAB.Cache
705705
assert.NotNil(t, cache)
706706
if defaultCache, ok := cache["default"].(string); ok {
707707
assert.Equal(t, "redis", defaultCache)

config.yaml

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -213,15 +213,49 @@ client:
213213
segmentsCache:
214214
default: "in-memory"
215215
services:
216-
in-memory:
216+
in-memory:
217217
size: 10000
218218
timeout: 600s
219-
# redis:
219+
# redis:
220220
# host: "localhost:6379"
221221
# password: ""
222222
# database: 0
223223
# timeout: 0s
224-
224+
225+
## Contextual Multi-Armed Bandit configuration
226+
cmab:
227+
## timeout for CMAB API requests
228+
requestTimeout: 10s
229+
## CMAB cache configuration
230+
## Supports both in-memory (single instance) and Redis (multi-instance) caching
231+
cache:
232+
## default cache service to use
233+
default: "in-memory"
234+
services:
235+
## in-memory cache (fast, isolated per Agent instance)
236+
in-memory:
237+
## maximum number of entries for in-memory cache
238+
size: 10000
239+
## time-to-live for cached decisions
240+
timeout: 30m
241+
## Redis cache (shared across multiple Agent instances)
242+
## Uncomment and configure for multi-instance deployments
243+
# redis:
244+
# host: "localhost:6379"
245+
# password: ""
246+
# database: 0
247+
# timeout: 30m
248+
## retry configuration for CMAB API requests
249+
retryConfig:
250+
## maximum number of retry attempts (in addition to the initial request)
251+
## maxRetries: 1 means up to 2 total attempts (1 initial + 1 retry)
252+
maxRetries: 1
253+
## initial backoff duration
254+
initialBackoff: 100ms
255+
## maximum backoff duration
256+
maxBackoff: 10s
257+
## multiplier for exponential backoff
258+
backoffMultiplier: 2.0
225259

226260
##
227261
## optimizely runtime configuration can be used for debugging and profiling the go runtime.
@@ -266,39 +300,3 @@ synchronization:
266300
datafile:
267301
enable: false
268302
default: "redis"
269-
270-
##
271-
## cmab: Contextual Multi-Armed Bandit configuration
272-
##
273-
cmab:
274-
## timeout for CMAB API requests
275-
requestTimeout: 10s
276-
## CMAB cache configuration
277-
## Supports both in-memory (single instance) and Redis (multi-instance) caching
278-
cache:
279-
## default cache service to use
280-
default: "in-memory"
281-
services:
282-
## in-memory cache (fast, isolated per Agent instance)
283-
in-memory:
284-
## maximum number of entries for in-memory cache
285-
size: 10000
286-
## time-to-live for cached decisions
287-
timeout: 30m
288-
## Redis cache (shared across multiple Agent instances)
289-
## Uncomment and configure for multi-instance deployments
290-
# redis:
291-
# host: "localhost:6379"
292-
# password: ""
293-
# database: 0
294-
# timeout: 30m
295-
## retry configuration for CMAB API requests
296-
retryConfig:
297-
## maximum number of retry attempts
298-
maxRetries: 3
299-
## initial backoff duration
300-
initialBackoff: 100ms
301-
## maximum backoff duration
302-
maxBackoff: 10s
303-
## multiplier for exponential backoff
304-
backoffMultiplier: 2.0

0 commit comments

Comments
 (0)