Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add timeout to fetchAndActivate #160

Merged
merged 11 commits into from
Jul 16, 2024
6 changes: 5 additions & 1 deletion Sources/Confidence/Confidence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ extension Confidence {
internal var region: ConfidenceRegion = .global
internal var metadata: ConfidenceMetadata?
internal var initialContext: ConfidenceStruct = [:]
internal var timeout: Double = 0
internal var timeout: Double = 10

// Injectable for testing
internal var flagApplier: FlagApplier?
Expand Down Expand Up @@ -339,6 +339,10 @@ extension Confidence {
return self
}

/**
Sets the timeout for the network requests to the Confidence backend.
The default is 10 seconds.
*/
public func withTimeout(timeout: Double) -> Builder {
nickybondarenko marked this conversation as resolved.
Show resolved Hide resolved
self.timeout = timeout
return self
Expand Down
1 change: 0 additions & 1 deletion Sources/Confidence/Http/NetworkClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ final class NetworkClient: HttpClient {
?? {
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = defaultHeaders
configuration.timeoutIntervalForRequest = timeoutIntervalForRequests

return URLSession(configuration: configuration)
}()
Expand Down
39 changes: 39 additions & 0 deletions Tests/ConfidenceTests/ConfidenceTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -581,6 +581,45 @@ class ConfidenceTest: XCTestCase {
XCTAssertEqual(error as? ConfidenceError, ConfidenceError.invalidContextInMessage)
}
}

func testRequestTimedOut() async throws {
class FakeClient: ConfidenceResolveClient {
var resolvedValues: [ResolvedValue] = []
func resolve(ctx: ConfidenceStruct) async throws -> ResolvesResult {
try await Task.sleep(nanoseconds: 5000000000)
return .init(resolvedValues: resolvedValues, resolveToken: "token")
}
}

let client = FakeClient()
client.resolvedValues = [
ResolvedValue(
variant: "default",
value: .init(structure: ["size": .init(integer: 3)]),
flag: "flag",
resolveReason: .match)
]

let confidence = Confidence.Builder(clientSecret: "test")
.withContext(initialContext: ["targeting_key": .init(string: "user2")])
.withFlagResolverClient(flagResolver: client)
.withFlagApplier(flagApplier: flagApplier)
.withTimeout(timeout: 1)
.build()

try await confidence.fetchAndActivate()
let evaluation = try confidence.getEvaluation(
key: "flag.size",
defaultValue: 0)

XCTAssertEqual(evaluation.value, 3)
nickybondarenko marked this conversation as resolved.
Show resolved Hide resolved
XCTAssertNil(evaluation.errorCode)
XCTAssertNil(evaluation.errorMessage)
XCTAssertEqual(evaluation.reason, .match)
XCTAssertEqual(evaluation.variant, "default")
await fulfillment(of: [flagApplier.applyExpectation], timeout: 1)
XCTAssertEqual(flagApplier.applyCallCount, 1)
}
}

final class DispatchQueueFake: DispatchQueueType {
Expand Down