Skip to content

Commit

Permalink
WIP - Use while loop to prevent duplicate config GET requests & bool …
Browse files Browse the repository at this point in the history
…flag

Signed-off-by: Jax DesMarais-Leder <[email protected]>
  • Loading branch information
scannillo authored and jaxdesmarais committed Aug 7, 2024
1 parent d546f2e commit 8f8b5ab
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 19 deletions.
18 changes: 7 additions & 11 deletions Sources/BraintreeCore/BTAPIClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,15 @@ import Foundation
/// cached on subsequent calls for better performance.
@_documentation(visibility: private)
public func fetchOrReturnRemoteConfiguration(_ completion: @escaping (BTConfiguration?, Error?) -> Void) {
configurationLoader.getConfig { [weak self] configuration, error in
guard let self else {
completion(nil, BTAPIClientError.deallocated)
return
}

if let error {
// TODO: - Consider updating all feature clients to use async version of this method?
Task {
do {
let configuration = try await configurationLoader.getConfig()
setupHTTPCredentials(configuration)
completion(configuration, nil)
} catch {
completion(nil, error)
return
}

setupHTTPCredentials(configuration)
completion(configuration, nil)
}
}

Expand Down
13 changes: 13 additions & 0 deletions Sources/BraintreeCore/BTHTTP.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ class BTHTTP: NSObject, URLSessionTaskDelegate {
completion(nil, nil, error)
}
}

func get(_ path: String, configuration: BTConfiguration? = nil, parameters: Encodable? = nil) async throws -> (BTJSON, HTTPURLResponse) {
try await withCheckedThrowingContinuation { continuation in
get(path, configuration: configuration, parameters: parameters) { body, response, error in
if let error {
continuation.resume(throwing: error)
} else if let body, let response {
continuation.resume(returning: (body, response))
}
}
// TODO: - How do we want to handle case of nil body or response
}
}

// TODO: - Remove when all POST bodies use Codable, instead of BTJSON/raw dictionaries
func post(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import Foundation

// TODO: - Do we still need this class? It no-longer wraps an array to provide thread-safety

/// Used to store, access, and manage an array of to-be-invoked `BTConfiguration` GET result callbacks
class ConfigurationCallbackStorage {

// TODO: - Remove. Not an option to store array of completions.
private var pendingCompletions: [(BTConfiguration?, Error?) -> Void] = []

/// The number of completions that are waiting to be invoked
Expand Down
38 changes: 30 additions & 8 deletions Sources/BraintreeCore/Configuration/ConfigurationLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ class ConfigurationLoader {
private let configurationCache = ConfigurationCache.shared
private let http: BTHTTP
private let pendingCompletions = ConfigurationCallbackStorage()

private var isConfigCached = false // TODO: - Rename; should this bool live here?

// MARK: - Intitializer

init(http: BTHTTP) {
Expand Down Expand Up @@ -69,17 +70,38 @@ class ConfigurationLoader {
}
}
}

func getConfig() async throws -> BTConfiguration {
try await withCheckedThrowingContinuation { continuation in
getConfig { configuration, error in
if let error {
continuation.resume(throwing: error)
} else if let configuration {
continuation.resume(returning: configuration)
if let cachedConfig = try? configurationCache.getFromCache(authorization: http.authorization.bearer) {
isConfigCached = true
return cachedConfig
}

while !isConfigCached {
print("While loop body")

do {
print("🤞GET request made")
let (body, response) = try await http.get(configPath, parameters: BTConfigurationRequest())

if response.statusCode != 200 { // || body == nil {
throw BTAPIClientError.configurationUnavailable
} else {
let configuration = BTConfiguration(json: body)

try? configurationCache.putInCache(authorization: http.authorization.bearer, configuration: configuration)

NotificationCenter.default.post(name: Notification.Name("ConfigGet"), object: configuration)
isConfigCached = true

return configuration
}
} catch {
throw error
}
}
print("Exited while loop")
throw BTAPIClientError.configurationUnavailable
}

// MARK: - Private Methods
Expand Down

0 comments on commit 8f8b5ab

Please sign in to comment.