Skip to content

Commit d3e0662

Browse files
refactor: adjust CmabCache inheritance to typealias and update cache timeout calculation
1 parent 9f575fe commit d3e0662

File tree

4 files changed

+32
-28
lines changed

4 files changed

+32
-28
lines changed

Sources/CMAB/CmabCache.swift

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,4 @@ import Foundation
1919
let DEFAULT_CMAB_CACHE_TIMEOUT = 30 * 60 // 30 minutes
2020
let DEFAULT_CMAB_CACHE_SIZE = 100
2121

22-
class CmabCache: LruCache<String, CmabCacheValue> {
23-
override func lookup(key: String) -> CmabCacheValue? {
24-
if timeoutInSecs <= 0 {
25-
return nil
26-
}
27-
return super.lookup(key: key)
28-
}
29-
}
22+
typealias CmabCache = LruCache<String, CmabCacheValue>

Sources/CMAB/CmabService.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,9 @@ extension DefaultCmabService {
198198
}
199199

200200
static func createDefault(cacheSize: Int, cacheTimeout: Int) -> DefaultCmabService {
201-
let cache = CmabCache(size: cacheSize, timeoutInSecs: cacheTimeout)
201+
// if cache timeout is set to 0 or negative, use default timeout
202+
let timeout = cacheTimeout <= 0 ? DEFAULT_CMAB_CACHE_TIMEOUT : cacheTimeout
203+
let cache = CmabCache(size: cacheSize, timeoutInSecs: timeout)
202204
return DefaultCmabService(cmabClient: DefaultCmabClient(), cmabCache: cache)
203205
}
204206
}

Tests/OptimizelyTests-APIs/OptimizelyClientTests_ODP.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class OptimizelyClientTests_ODP: XCTestCase {
5353
cmabCacheSize: 50,
5454
cmabCacheTimeoutInSecs: 120)
5555
var optimizely = OptimizelyClient(sdkKey: OTUtils.randomSdkKey, settings: sdkSettings)
56-
let cmabCache = ((optimizely.decisionService as! DefaultDecisionService).cmabService as! DefaultCmabService).cmabCache
56+
var cmabCache = ((optimizely.decisionService as! DefaultDecisionService).cmabService as! DefaultCmabService).cmabCache
5757
XCTAssertEqual(50, cmabCache.maxSize)
5858
XCTAssertEqual(120, cmabCache.timeoutInSecs)
5959
XCTAssertEqual(12, optimizely.odpManager.segmentManager?.segmentsCache.maxSize)
@@ -64,6 +64,13 @@ class OptimizelyClientTests_ODP: XCTestCase {
6464
optimizely = OptimizelyClient(sdkKey: OTUtils.randomSdkKey, settings: sdkSettings)
6565
XCTAssertEqual(34, optimizely.odpManager.segmentManager?.apiMgr.resourceTimeoutInSecs)
6666
XCTAssertEqual(45, optimizely.odpManager.eventManager?.apiMgr.resourceTimeoutInSecs)
67+
68+
sdkSettings = OptimizelySdkSettings(cmabCacheSize: 50, cmabCacheTimeoutInSecs: -10)
69+
70+
optimizely = OptimizelyClient(sdkKey: OTUtils.randomSdkKey, settings: sdkSettings)
71+
cmabCache = ((optimizely.decisionService as! DefaultDecisionService).cmabService as! DefaultCmabService).cmabCache
72+
XCTAssertEqual(50, cmabCache.maxSize)
73+
XCTAssertEqual(1800, cmabCache.timeoutInSecs)
6774

6875
sdkSettings = OptimizelySdkSettings(disableOdp: true)
6976
optimizely = OptimizelyClient(sdkKey: OTUtils.randomSdkKey, settings: sdkSettings)

Tests/OptimizelyTests-Common/CmabServiceTests.swift

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,8 @@ extension DefaultCmabServiceTests {
717717
}
718718

719719
func testCacheTimeoutZero() {
720-
// Create a cache with timeout 0 (immediate expiration)
720+
// When timeout is 0, LruCache uses default timeout (30 * 60 seconds = 1800 seconds)
721+
// So cache will NOT expire within the test timeframe
721722
let zeroTimeoutCache = CmabCache(size: 10, timeoutInSecs: 0)
722723
let zeroTimeoutService = DefaultCmabService(cmabClient: cmabClient, cmabCache: zeroTimeoutCache)
723724

@@ -733,48 +734,49 @@ extension DefaultCmabServiceTests {
733734
options: []
734735
) { result in
735736
switch result {
736-
case .success(let decision):
737-
XCTAssertEqual(decision.variationId, "variation-first")
738-
XCTAssertTrue(self.cmabClient.fetchDecisionCalled, "Should call API on first request")
739-
740-
case .failure(let error):
741-
XCTFail("Expected success but got error: \(error)")
737+
case .success(let decision):
738+
XCTAssertEqual(decision.variationId, "variation-first")
739+
XCTAssertTrue(self.cmabClient.fetchDecisionCalled, "Should call API on first request")
740+
741+
case .failure(let error):
742+
XCTFail("Expected success but got error: \(error)")
742743
}
743744
expectation1.fulfill()
744745
}
745746

746747
wait(for: [expectation1], timeout: 1.0)
747748

748-
// Reset and change the variation
749+
// Reset client but don't change the result
749750
cmabClient.reset()
750751
cmabClient.fetchDecisionResult = .success("variation-second")
751752

752-
// Small delay to ensure cache timeout
753-
Thread.sleep(forTimeInterval: 1.1)
753+
// Small delay (but not enough to expire default 1800s timeout)
754+
Thread.sleep(forTimeInterval: 0.1)
754755

755756
let expectation2 = self.expectation(description: "second request")
756757

757-
// Second request - should NOT use cache (timeout = 0, cache expired)
758+
// Second request - SHOULD use cache (timeout defaults to 1800s, not expired)
758759
zeroTimeoutService.getDecision(
759760
config: config,
760761
userContext: userContext,
761762
ruleId: "exp-123",
762763
options: []
763764
) { result in
764765
switch result {
765-
case .success(let decision):
766-
XCTAssertEqual(decision.variationId, "variation-second")
767-
XCTAssertTrue(self.cmabClient.fetchDecisionCalled, "Should call API again when cache timeout is 0")
768-
769-
case .failure(let error):
770-
XCTFail("Expected success but got error: \(error)")
766+
case .success(let decision):
767+
// Should get cached value, not the new one
768+
XCTAssertEqual(decision.variationId, "variation-first")
769+
XCTAssertFalse(self.cmabClient.fetchDecisionCalled, "Should use cache when timeout defaults to 1800s")
770+
771+
case .failure(let error):
772+
XCTFail("Expected success but got error: \(error)")
771773
}
772774
expectation2.fulfill()
773775
}
774776

775777
wait(for: [expectation2], timeout: 1.0)
776778
}
777-
779+
778780
func testCacheSizeZeroAndTimeoutZero() {
779781
// Create a cache with both size 0 and timeout 0 (completely disabled)
780782
let disabledCache = CmabCache(size: 0, timeoutInSecs: 0)

0 commit comments

Comments
 (0)