Skip to content

Commit

Permalink
fix: Address in transit cache on startup (#71)
Browse files Browse the repository at this point in the history
Signed-off-by: Fabrizio Demaria <fdema@spotify.com>
  • Loading branch information
fabriziodemaria authored Jan 16, 2024
1 parent f169d90 commit a090f3e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Sources/ConfidenceProvider/Cache/CacheDataInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ final actor CacheDataInteractor: CacheDataActor {
var cache = CacheData.empty()

init(cacheData: CacheData) {
cache = cacheData
cache = CacheData.convertInTransit(cache: cacheData)
}

func add(resolveToken: String, flagName: String, applyTime: Date) -> (CacheData, Bool) {
Expand Down
11 changes: 11 additions & 0 deletions Sources/ConfidenceProvider/Cache/Models/CacheData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ struct CacheData: Codable {
self.resolveEvents = resolveEvents
}

static func convertInTransit(cache: CacheData) -> CacheData {
var mutatedCache = cache
for resolveIndex in 0..<mutatedCache.resolveEvents.count {
for eventIndex in 0..<mutatedCache.resolveEvents[resolveIndex].events.count
where mutatedCache.resolveEvents[resolveIndex].events[eventIndex].status == .sending {
mutatedCache.resolveEvents[resolveIndex].events[eventIndex].status = .created
}
}
return mutatedCache
}

static func empty() -> CacheData {
CacheData(resolveEvents: [])
}
Expand Down
32 changes: 32 additions & 0 deletions Tests/ConfidenceProviderTests/FlagApplierWithRetriesTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,38 @@ class FlagApplierWithRetriesTest: XCTestCase {
XCTAssertEqual(request.flags.count, 20)
}

func test_previoslyStoredInTransitData_batchTriggered() async throws {
// Given storage that has previously stored data (100 records, same token)
let prefilledStorage = StorageMock()
var prefilledCache = try CacheDataUtility.prefilledCacheData(applyEventCount: 100)
// Set all the events in the cache/storage as in-transit, i.e. `sending`
prefilledCache.setEventStatus(resolveToken: "token0", status: .sending)
try prefilledStorage.save(data: prefilledCache)

let expectation = self.expectation(description: "Waiting for network call to complete")
expectation.expectedFulfillmentCount = 5
httpClient.expectation = expectation

let storageExpectation = self.expectation(description: "Waiting for storage expectation to be completed")
storageExpectation.expectedFulfillmentCount = 10
prefilledStorage.saveExpectation = storageExpectation

// When flag applier is initialised
_ = FlagApplierWithRetries(
httpClient: httpClient,
storage: prefilledStorage,
options: options,
metadata: metadata
)

await waitForExpectations(timeout: 5.0)

// Then http client sends 5 apply flag batch request, containing 20 records each
let request = try XCTUnwrap(httpClient.data?.first as? ApplyFlagsRequest)
XCTAssertEqual(httpClient.postCallCounter, 5)
XCTAssertEqual(request.flags.count, 20)
}

func testApply_previoslyStoredData_partialFailure() async throws {
// Given storage that has previously stored data (100 records, same token)
let partiallyFailingHttpClient = HttpClientMock(testMode: .failFirstChunk)
Expand Down

0 comments on commit a090f3e

Please sign in to comment.