Skip to content

Commit

Permalink
fix: improving performance of FlagSynchronizer creation
Browse files Browse the repository at this point in the history
  • Loading branch information
tanderson-ld committed Jan 10, 2025
1 parent a378e29 commit f949980
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
6 changes: 2 additions & 4 deletions LaunchDarkly/LaunchDarkly/LDClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,15 @@ public class LDClient {
os_log("%s runMode aborted. Old runMode equals new runMode", log: config.logger, type: .debug, typeName(and: #function))
return
}

let cachedData = self.flagCache.getCachedData(cacheKey: self.context.fullyQualifiedHashedKey(), contextHash: self.context.contextHash())

let lastUpdated = self.flagCache.getCachedDataLastUpdatedDate(cacheKey: self.context.fullyQualifiedHashedKey(), contextHash: self.context.contextHash())
let willSetSynchronizerOnline = isOnline && isInSupportedRunMode
flagSynchronizer.isOnline = false
let streamingModeVar = ConnectionInformation.effectiveStreamingMode(config: config, ldClient: self)
connectionInformation = ConnectionInformation.backgroundBehavior(connectionInformation: connectionInformation, streamingMode: streamingModeVar, goOnline: willSetSynchronizerOnline)
flagSynchronizer = serviceFactory.makeFlagSynchronizer(streamingMode: streamingModeVar,
pollingInterval: config.flagPollingInterval(runMode: runMode),
useReport: config.useReport,
lastUpdated: cachedData.lastUpdated,
lastUpdated: lastUpdated,
service: service,
onSyncComplete: onFlagSyncComplete)
flagSynchronizer.isOnline = willSetSynchronizerOnline
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ protocol FeatureFlagCaching {
///
///
func getCachedData(cacheKey: String, contextHash: String) -> (items: StoredItems?, etag: String?, lastUpdated: Date?)

/// Retrieve the date the cache for the given key was last updated. See getCachedData for more information.
///
/// - parameter cacheKey: The index key into the local cache store.
/// - parameter contextHash: A hash value representing a fully unique context.
///
/// - returns: The date the cache was last considered up-to-date. If there are no cached
/// values, this should return nil.
func getCachedDataLastUpdatedDate(cacheKey: String, contextHash: String) -> Date?

// When we update the cache, we save the flag data and if we have it, an
// etag. For polling, we should always have the flag data and an etag
Expand Down Expand Up @@ -99,6 +108,19 @@ final class FeatureFlagCache: FeatureFlagCaching {

return (items: cachedFlags.flags, etag: etag, lastUpdated: Date(timeIntervalSince1970: TimeInterval(lastUpdated / 1_000)))
}

func getCachedDataLastUpdatedDate(cacheKey: String, contextHash: String) -> Date? {

var cachedContexts: [String: Int64] = [:]
if let cacheMetadata = keyedValueCache.data(forKey: "cached-contexts") {
cachedContexts = (try? JSONDecoder().decode([String: Int64].self, from: cacheMetadata)) ?? [:]
}

guard let lastUpdated = cachedContexts[cacheKey]
else { return nil }

return Date(timeIntervalSince1970: TimeInterval(lastUpdated / 1_000))
}

func saveCachedData(_ storedItems: StoredItems, cacheKey: String, contextHash: String, lastUpdated: Date, etag: String?) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,4 +178,22 @@ final class FeatureFlagCacheSpec: XCTestCase {
let setMetadata = try JSONDecoder().decode([String: Int64].self, from: mockValueCache.setReceivedArguments!.value)
XCTAssertEqual(setMetadata, [hashedContextKey: now.millisSince1970])
}

func testGetCachedDataLastUpdatedDate() {
let now = Date()
let flagCache = FeatureFlagCache(serviceFactory: ClientServiceFactory(logger: .disabled), mobileKey: "abc", maxCachedContexts: 5)
flagCache.saveCachedData(testFlagCollection.flags, cacheKey: "key", contextHash: "hash", lastUpdated: now, etag: "example-etag")

let lastUpdated = flagCache.getCachedDataLastUpdatedDate(cacheKey: "key", contextHash: "hash")
XCTAssertEqual(lastUpdated!.millisSince1970, now.millisSince1970, accuracy: 1_000)
}

func testGetCachedDataLastUpdatedDateKeyDoesntExist() {
let now = Date()
let flagCache = FeatureFlagCache(serviceFactory: ClientServiceFactory(logger: .disabled), mobileKey: "abc", maxCachedContexts: 5)
flagCache.saveCachedData(testFlagCollection.flags, cacheKey: "key", contextHash: "hash", lastUpdated: now, etag: "example-etag")

let lastUpdated = flagCache.getCachedDataLastUpdatedDate(cacheKey: "bogus", contextHash: "bogusHash")
XCTAssertEqual(lastUpdated, nil)
}
}

0 comments on commit f949980

Please sign in to comment.