Skip to content

Commit ba1eeff

Browse files
authored
[FSSDK-11635] remove duplicated fetch method, add cache wrapper (#409)
* remove duplicated fetch method, add cache wrapper * add cache wrapper for new code * clean up test
1 parent 0d843a4 commit ba1eeff

File tree

2 files changed

+55
-38
lines changed

2 files changed

+55
-38
lines changed

pkg/cmab/service.go

Lines changed: 15 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"encoding/json"
2222
"fmt"
2323
"strconv"
24-
"time"
2524

2625
"github.com/google/uuid"
2726
"github.com/optimizely/go-sdk/v2/pkg/cache"
@@ -76,7 +75,7 @@ func (s *DefaultCmabService) GetDecision(
7675
// Check if we should ignore the cache
7776
if options != nil && hasOption(options, decide.IgnoreCMABCache) {
7877
reasons = append(reasons, "Ignoring CMAB cache as requested")
79-
decision, err := s.fetchDecisionWithRetry(ruleID, userContext.ID, filteredAttributes)
78+
decision, err := s.fetchDecision(ruleID, userContext.ID, filteredAttributes)
8079
if err != nil {
8180
return Decision{Reasons: reasons}, err
8281
}
@@ -136,7 +135,7 @@ func (s *DefaultCmabService) GetDecision(
136135
}
137136

138137
// Fetch new decision
139-
decision, err := s.fetchDecisionWithRetry(ruleID, userContext.ID, filteredAttributes)
138+
decision, err := s.fetchDecision(ruleID, userContext.ID, filteredAttributes)
140139
if err != nil {
141140
decision.Reasons = append(reasons, decision.Reasons...)
142141
return decision, fmt.Errorf("CMAB API error: %w", err)
@@ -156,51 +155,29 @@ func (s *DefaultCmabService) GetDecision(
156155
return decision, nil
157156
}
158157

159-
// fetchDecisionWithRetry fetches a decision from the CMAB API with retry logic
160-
func (s *DefaultCmabService) fetchDecisionWithRetry(
158+
// fetchDecision fetches a decision from the CMAB API
159+
func (s *DefaultCmabService) fetchDecision(
161160
ruleID string,
162161
userID string,
163162
attributes map[string]interface{},
164163
) (Decision, error) {
165164
cmabUUID := uuid.New().String()
166165
reasons := []string{}
167166

168-
// Retry configuration
169-
maxRetries := 3
170-
backoffFactor := 2
171-
initialBackoff := 100 * time.Millisecond
167+
s.logger.Debug(fmt.Sprintf("Fetching CMAB decision for rule %s and user %s", ruleID, userID))
172168

173-
var lastErr error
174-
175-
for attempt := 0; attempt < maxRetries; attempt++ {
176-
// Exponential backoff if this is a retry
177-
if attempt > 0 {
178-
backoffDuration := initialBackoff * time.Duration(backoffFactor^attempt)
179-
time.Sleep(backoffDuration)
180-
reasons = append(reasons, fmt.Sprintf("Retry attempt %d/%d after backoff", attempt+1, maxRetries))
181-
}
182-
183-
s.logger.Debug(fmt.Sprintf("Fetching CMAB decision for rule %s and user %s (attempt %d/%d)",
184-
ruleID, userID, attempt+1, maxRetries))
185-
186-
variationID, err := s.cmabClient.FetchDecision(ruleID, userID, attributes, cmabUUID)
187-
if err == nil {
188-
reasons = append(reasons, fmt.Sprintf("Successfully fetched CMAB decision on attempt %d/%d", attempt+1, maxRetries))
189-
return Decision{
190-
VariationID: variationID,
191-
CmabUUID: cmabUUID,
192-
Reasons: reasons,
193-
}, nil
194-
}
195-
196-
lastErr = err
197-
s.logger.Warning(fmt.Sprintf("CMAB API request failed (attempt %d/%d): %v",
198-
attempt+1, maxRetries, err))
169+
variationID, err := s.cmabClient.FetchDecision(ruleID, userID, attributes, cmabUUID)
170+
if err != nil {
171+
reasons = append(reasons, "Failed to fetch CMAB decision")
172+
return Decision{Reasons: reasons}, fmt.Errorf("CMAB API error: %w", err)
199173
}
200174

201-
reasons = append(reasons, fmt.Sprintf("Failed to fetch CMAB decision after %d attempts", maxRetries))
202-
return Decision{Reasons: reasons}, fmt.Errorf("failed to fetch CMAB decision after %d attempts: %w",
203-
maxRetries, lastErr)
175+
reasons = append(reasons, "Successfully fetched CMAB decision")
176+
return Decision{
177+
VariationID: variationID,
178+
CmabUUID: cmabUUID,
179+
Reasons: reasons,
180+
}, nil
204181
}
205182

206183
// filterAttributes filters user attributes based on CMAB configuration

pkg/odp/cache.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/****************************************************************************
2+
* Copyright 2022-2025, Optimizely, Inc. and contributors *
3+
* *
4+
* Licensed under the Apache License, Version 2.0 (the "License"); *
5+
* you may not use this file except in compliance with the License. *
6+
* You may obtain a copy of the License at *
7+
* *
8+
* https://www.apache.org/licenses/LICENSE-2.0 *
9+
* *
10+
* Unless required by applicable law or agreed to in writing, software *
11+
* distributed under the License is distributed on an "AS IS" BASIS, *
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13+
* See the License for the specific language governing permissions and *
14+
* limitations under the License. *
15+
***************************************************************************/
16+
17+
// Package odp provides compatibility with the previously located cache package.
18+
// This file exists to maintain backward compatibility with code that imports
19+
// cache from the odp package. New code should import from pkg/cache directly.
20+
package odp
21+
22+
import (
23+
"time"
24+
25+
"github.com/optimizely/go-sdk/v2/pkg/cache"
26+
)
27+
28+
// LRUCache wraps the cache.LRUCache to maintain backward compatibility
29+
type LRUCache struct {
30+
*cache.LRUCache
31+
}
32+
33+
// NewLRUCache returns a new instance of Least Recently Used in-memory cache
34+
// Deprecated: For new code, use pkg/cache directly instead.
35+
// This function exists for backward compatibility with code that imports from pkg/odp
36+
func NewLRUCache(size int, timeout time.Duration) *LRUCache {
37+
return &LRUCache{
38+
LRUCache: cache.NewLRUCache(size, timeout),
39+
}
40+
}

0 commit comments

Comments
 (0)