Skip to content

Commit

Permalink
feat: add timeout to fetchAndActivate (#160)
Browse files Browse the repository at this point in the history
* feat: add timeout to fetchAndActivate
  • Loading branch information
nickybondarenko authored Jul 16, 2024
1 parent c8437ac commit ea18479
Show file tree
Hide file tree
Showing 11 changed files with 63 additions and 25 deletions.
20 changes: 17 additions & 3 deletions Sources/Confidence/Confidence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ public class Confidence: ConfidenceEventSender {
storage: storage,
context: context,
parent: self,
debugLogger: debugLogger)
debugLogger: debugLogger
)
}

private func withLock(callback: @escaping (Confidence) -> Void) {
Expand All @@ -297,6 +298,7 @@ extension Confidence {
// Can be configured
internal var region: ConfidenceRegion = .global
internal var initialContext: ConfidenceStruct = [:]
internal var timeout: Double = 10

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

/**
Set the timeout for the network request, defaulting to 10 seconds.
*/
public func withTimeout(timeout: Double) -> Builder {
self.timeout = timeout
return self
}

/**
Build the Confidence instance.
*/
Expand All @@ -368,7 +378,8 @@ extension Confidence {
}
let options = ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: clientSecret),
region: region)
region: region,
timeoutIntervalForRequest: timeout)
let metadata = ConfidenceMetadata(
name: sdkId,
version: "0.2.4") // x-release-please-version
Expand All @@ -377,7 +388,10 @@ extension Confidence {
metadata: metadata,
debugLogger: debugLogger
)
let httpClient = NetworkClient(baseUrl: BaseUrlMapper.from(region: options.region))
let httpClient = NetworkClient(
baseUrl: BaseUrlMapper.from(region: options.region),
timeoutIntervalForRequests: options.timeoutIntervalForRequest
)
let flagApplier = flagApplier ?? FlagApplierWithRetries(
httpClient: httpClient,
storage: DefaultStorage(filePath: "confidence.flags.apply"),
Expand Down
5 changes: 4 additions & 1 deletion Sources/Confidence/ConfidenceClientOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ struct ConfidenceClientOptions {
public var credentials: ConfidenceClientCredentials
public var region: ConfidenceRegion
public var initializationStrategy: InitializationStrategy
public var timeoutIntervalForRequest: Double

public init(
credentials: ConfidenceClientCredentials,
region: ConfidenceRegion? = nil,
initializationStrategy: InitializationStrategy = .fetchAndActivate
initializationStrategy: InitializationStrategy = .fetchAndActivate,
timeoutIntervalForRequest: Double
) {
self.credentials = credentials
self.region = region ?? .global
self.initializationStrategy = initializationStrategy
self.timeoutIntervalForRequest = timeoutIntervalForRequest
}
}

Expand Down
5 changes: 4 additions & 1 deletion Sources/Confidence/Http/NetworkClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ final class NetworkClient: HttpClient {
private let retry: Retry
private let session: URLSession
private let baseUrl: String
private var timeoutIntervalForRequests: Double

public init(
session: URLSession? = nil,
baseUrl: String,
defaultHeaders: [String: String] = [:],
retry: Retry = .none
retry: Retry = .none,
timeoutIntervalForRequests: Double
) {
self.session =
session
Expand All @@ -24,6 +26,7 @@ final class NetworkClient: HttpClient {
self.headers = defaultHeaders
self.retry = retry
self.baseUrl = baseUrl
self.timeoutIntervalForRequests = timeoutIntervalForRequests
}

public func post<T: Decodable>(
Expand Down
6 changes: 5 additions & 1 deletion Sources/Confidence/RemoteConfidenceClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ public class RemoteConfidenceClient: ConfidenceClient {
case .usa:
self.baseUrl = "https://events.us.confidence.dev/v1/events"
}
self.httpClient = NetworkClient(session: session, baseUrl: baseUrl)
self.httpClient = NetworkClient(
session: session,
baseUrl: baseUrl,
timeoutIntervalForRequests: options.timeoutIntervalForRequest
)
self.metadata = metadata
self.debugLogger = debugLogger
}
Expand Down
3 changes: 2 additions & 1 deletion Sources/Confidence/RemoteResolveConfidenceClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class RemoteConfidenceResolveClient: ConfidenceResolveClient {
self.metadata = metadata
self.httpClient = NetworkClient(
session: session,
baseUrl: BaseUrlMapper.from(region: options.region))
baseUrl: BaseUrlMapper.from(region: options.region),
timeoutIntervalForRequests: options.timeoutIntervalForRequest)
}

// MARK: Resolver
Expand Down
20 changes: 10 additions & 10 deletions Tests/ConfidenceTests/ConfidenceContextTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ final class ConfidenceContextTests: XCTestCase {
func testWithContext() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand All @@ -33,7 +33,7 @@ final class ConfidenceContextTests: XCTestCase {
func testWithContextUpdateParent() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down Expand Up @@ -65,7 +65,7 @@ final class ConfidenceContextTests: XCTestCase {
func testUpdateLocalContext() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand All @@ -92,7 +92,7 @@ final class ConfidenceContextTests: XCTestCase {
func testUpdateLocalContextWithoutOverride() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down Expand Up @@ -123,7 +123,7 @@ final class ConfidenceContextTests: XCTestCase {
func testUpdateParentContextWithOverride() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down Expand Up @@ -154,7 +154,7 @@ final class ConfidenceContextTests: XCTestCase {
func testRemoveContextEntry() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand All @@ -179,7 +179,7 @@ final class ConfidenceContextTests: XCTestCase {
func testRemoveContextEntryFromParent() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down Expand Up @@ -207,7 +207,7 @@ final class ConfidenceContextTests: XCTestCase {
func testRemoveContextEntryFromParentAndChild() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down Expand Up @@ -238,7 +238,7 @@ final class ConfidenceContextTests: XCTestCase {
func testRemoveContextEntryFromParentAndChildThenUpdate() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down Expand Up @@ -271,7 +271,7 @@ final class ConfidenceContextTests: XCTestCase {
func testVisitorId() {
let client = RemoteConfidenceResolveClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down
10 changes: 8 additions & 2 deletions Tests/ConfidenceTests/EventSenderEngineTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,10 @@ final class EventSenderEngineTest: XCTestCase {
func testRemoveEventsFromStorageOnBadRequest() throws {
MockedClientURLProtocol.mockedOperation = .badRequest
let badRequestUploader = RemoteConfidenceClient(
options: ConfidenceClientOptions(credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: ""),
timeoutIntervalForRequest: 10
),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand All @@ -135,7 +138,10 @@ final class EventSenderEngineTest: XCTestCase {
func testKeepEventsInStorageForRetry() throws {
MockedClientURLProtocol.mockedOperation = .needRetryLater
let retryLaterUploader = RemoteConfidenceClient(
options: ConfidenceClientOptions(credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: ""),
timeoutIntervalForRequest: 10
),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down
5 changes: 4 additions & 1 deletion Tests/ConfidenceTests/FlagApplierWithRetriesTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import XCTest

@available(macOS 13.0, iOS 16.0, *)
class FlagApplierWithRetriesTest: XCTestCase {
private let options = ConfidenceClientOptions(credentials: .clientSecret(secret: "test"))
private let options = ConfidenceClientOptions(
credentials: .clientSecret(secret: "test"),
timeoutIntervalForRequest: 10
)
private var storage = StorageMock()
private var httpClient = HttpClientMock()
private let metadata = ConfidenceMetadata(name: "test-provider-name", version: "0.0.0.")
Expand Down
8 changes: 4 additions & 4 deletions Tests/ConfidenceTests/RemoteConfidenceClientTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class RemoteConfidenceClientTest: XCTestCase {
func testUploadDoesntThrow() async throws {
let client = RemoteConfidenceClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand All @@ -29,7 +29,7 @@ class RemoteConfidenceClientTest: XCTestCase {
func testUploadEmptyEventsDoesntThrow() async throws {
let client = RemoteConfidenceClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand All @@ -41,7 +41,7 @@ class RemoteConfidenceClientTest: XCTestCase {
MockedClientURLProtocol.mockedOperation = .firstEventFails
let client = RemoteConfidenceClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand All @@ -59,7 +59,7 @@ class RemoteConfidenceClientTest: XCTestCase {
MockedClientURLProtocol.mockedOperation = .malformedResponse
let client = RemoteConfidenceClient(
options: ConfidenceClientOptions(
credentials: ConfidenceClientCredentials.clientSecret(secret: "")),
credentials: ConfidenceClientCredentials.clientSecret(secret: ""), timeoutIntervalForRequest: 10),
session: MockedClientURLProtocol.mockedSession(),
metadata: ConfidenceMetadata(name: "", version: ""))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class RemoteResolveConfidenceClientTest: XCTestCase {
let session = MockedResolveClientURLProtocol.mockedSession(flags: flags)

let client = RemoteConfidenceResolveClient(
options: .init(credentials: .clientSecret(secret: "test")),
options: .init(credentials: .clientSecret(secret: "test"), timeoutIntervalForRequest: 10),
session: session,
applyOnResolve: true,
metadata: ConfidenceMetadata(name: "", version: "")
Expand Down
4 changes: 4 additions & 0 deletions api/Confidence_public_api.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
"name": "withRegion(region:)",
"declaration": "public func withRegion(region: ConfidenceRegion) -> Builder"
},
{
"name": "withTimeout(timeout:)",
"declaration": "public func withTimeout(timeout: Double) -> Builder"
},
{
"name": "build()",
"declaration": "public func build() -> Confidence"
Expand Down

0 comments on commit ea18479

Please sign in to comment.