Skip to content

Commit

Permalink
fix: call fetch on start by default (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
bgiori authored Nov 9, 2023
1 parent 014a5ae commit 66fea3b
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 46 deletions.
53 changes: 11 additions & 42 deletions Sources/Experiment/ExperimentClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,58 +108,27 @@ internal class DefaultExperimentClient : NSObject, ExperimentClient {
}
runningLock.signal()
setUser(user)
// Determine to fetch remove evaluation variants on start, either using the configured setting, or dynamically by checking the flag cache.
var remoteFlags = config.fetchOnStart?.boolValue ?? flagsStorageQueue.sync { self.flags.getAll() }.contains { (_, flag: EvaluationFlag) in
flag.isRemoteEvaluationMode()
}
startQueue.async {
var error: Error? = nil
if (remoteFlags) {
// We already have remote flags in our flag cache, so we know we need to
// evaluate remotely even before we've updated our flags.
let startGroup = DispatchGroup()
startGroup.enter()
startGroup.enter()
self.flagsInternal { e in
if let e = e {
error = e
}
startGroup.leave()
let fetchOnStart = self.config.fetchOnStart?.boolValue ?? true
let startGroup = DispatchGroup()
startGroup.enter()
self.flagsInternal { e in
if let e = e {
error = e
}
startGroup.leave()
}
if (fetchOnStart) {
startGroup.enter()
self.fetch(user: user) { _, e in
if let e = e {
error = e
}
startGroup.leave()
}
startGroup.wait()
} else {
// We don't know if remote evaluation is required, await the flag promise,
// and recheck for remote flags.
let flagsGroup = DispatchGroup()
flagsGroup.enter()
self.flagsInternal { e in
if let e = e {
error = e
}
flagsGroup.leave()
}
flagsGroup.wait()
remoteFlags = self.config.fetchOnStart?.boolValue ?? self.flagsStorageQueue.sync { self.flags.getAll() }.contains { (_, flag: EvaluationFlag) in
flag.isRemoteEvaluationMode()
}
if (remoteFlags) {
let fetchGroup = DispatchGroup()
fetchGroup.enter()
self.fetch(user: user) { _, e in
if let e = e {
error = e
}
fetchGroup.leave()
}
fetchGroup.wait()
}
}
startGroup.wait()
completion?(error)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/Experiment/ExperimentConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ import Foundation
static let fetchTimeoutMillis: Int = 10000
static let retryFetchOnFailure: Bool = true
static let automaticExposureTracking: Bool = true
static let fetchOnStart: NSNumber? = nil
static let fetchOnStart: NSNumber? = 1
static let pollOnStart: Bool = true
static let automaticFetchOnAmplitudeIdentityChange: Bool = false
static let userProvider: ExperimentUserProvider? = nil
Expand Down
6 changes: 3 additions & 3 deletions Tests/ExperimentTests/ExperimentClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1079,7 +1079,7 @@ class ExperimentClientTests: XCTestCase {
XCTAssertEqual("on", variant.value)
}

func testStart_WithLocalEvaluationOnly_DoesNotCallFetch() {
func testStart_WithLocalEvaluationOnly_CallsFetch() {
let storage = InMemoryStorage()
let config = ExperimentConfigBuilder()
.build()
Expand All @@ -1097,9 +1097,9 @@ class ExperimentClientTests: XCTestCase {
let user = ExperimentUserBuilder()
.build()
client.startBlocking(user: user)
XCTAssertEqual(0, client.fetchCalls)
client.fetchBlocking(user: user)
XCTAssertEqual(1, client.fetchCalls)
client.fetchBlocking(user: user)
XCTAssertEqual(2, client.fetchCalls)
}

func testStart_WithLocalEvalautionOnly_FetchOnStartEnabled_CallsFetch() {
Expand Down

0 comments on commit 66fea3b

Please sign in to comment.