Skip to content

Commit

Permalink
fix(swift): retry strategy (#2642)
Browse files Browse the repository at this point in the history
  • Loading branch information
Fluf22 committed Jan 31, 2024
1 parent eae9066 commit 39c94cc
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ class AlgoliaRetryStrategy: RetryStrategy {
return HostIterator { [weak self] in
guard let retryStrategy = self else { return nil }
return retryStrategy.queue.sync {
retryStrategy.hosts.first { $0.supports(callType) && $0.isUp }
retryStrategy.hosts
.sorted { $0.lastUpdated.compare($1.lastUpdated) == .orderedAscending }
.first { $0.supports(callType) && $0.isUp }
}
}
}
Expand Down
124 changes: 65 additions & 59 deletions templates/swift/client_configuration.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ public struct Configuration: Core.Configuration, Credentials {
writeTimeout: TimeInterval = DefaultConfiguration.default.writeTimeout,
readTimeout: TimeInterval = DefaultConfiguration.default.readTimeout,
logLevel: LogLevel = DefaultConfiguration.default.logLevel,
defaultHeaders: [String: String]? = DefaultConfiguration.default.defaultHeaders{{#isSearchClient}},
batchSize: Int = 1000{{/isSearchClient}}) throws {
defaultHeaders: [String: String]? = DefaultConfiguration.default.defaultHeaders,
hosts: [RetryableHost]? = nil{{#isSearchClient}},
batchSize: Int = 1000{{/isSearchClient}}
) throws {
guard !appId.isEmpty else {
throw AlgoliaError.invalidCredentials("appId")
}
Expand All @@ -52,72 +54,76 @@ public struct Configuration: Core.Configuration, Credentials {
"X-Algolia-API-Key": apiKey,
"Content-Type": "application/json"
].merging(defaultHeaders ?? [:]) { (_, new) in new }{{#isSearchClient}}

self.batchSize = batchSize{{/isSearchClient}}

{{^uniqueHost}}{{^hasRegionalHost}}
func buildHost(_ components: (suffix: String, callType: RetryableHost.CallTypeSupport)) throws
-> RetryableHost
{
guard let url = URL(string: "https://\(appId)\(components.suffix)") else {
throw AlgoliaError.runtimeError("Malformed URL")
}

return RetryableHost(url: url, callType: components.callType)
}
UserAgentController.append(UserAgent(title: "{{#lambda.client-to-name}}{{client}}{{/lambda.client-to-name}}", version: Version.current.description))

let hosts = try [
("-dsn.algolia.net", .read),
(".algolia.net", .write),
].map(buildHost)

let commonHosts = try [
("-1.algolianet.com", .universal),
("-2.algolianet.com", .universal),
("-3.algolianet.com", .universal),
].map(buildHost).shuffled()

self.hosts = hosts + commonHosts
{{/hasRegionalHost}}{{/uniqueHost}}
{{#uniqueHost}}
guard let url = URL(string: "https://{{{.}}}") else {
throw AlgoliaError.runtimeError("Malformed URL")
}
guard let hosts = hosts else {
{{^uniqueHost}}{{^hasRegionalHost}}
func buildHost(_ components: (suffix: String, callType: RetryableHost.CallTypeSupport)) throws
-> RetryableHost
{
guard let url = URL(string: "https://\(appId)\(components.suffix)") else {
throw AlgoliaError.runtimeError("Malformed URL")
}

self.hosts = [
.init(url: url)
]
{{/uniqueHost}}
{{#hasRegionalHost}}
guard {{#fallbackToAliasHost}}region == nil || {{/fallbackToAliasHost}}authorizedRegions.contains(region{{#fallbackToAliasHost}}!{{/fallbackToAliasHost}}) else {
throw AlgoliaError.runtimeError(
"`region` {{^fallbackToAliasHost}}is required and {{/fallbackToAliasHost}}must be one of the following: \(authorizedRegions.map { $0.rawValue }.joined(separator: ", "))"
)
return RetryableHost(url: url, callType: components.callType)
}

{{#fallbackToAliasHost}}
if let region = region {
{{/fallbackToAliasHost}}
guard let url = URL(string: "https://{{{regionalHost}}}".replacingOccurrences(of: "{region}", with: region.rawValue)) else {
throw AlgoliaError.runtimeError("Malformed URL")
}
let hosts = try [
("-dsn.algolia.net", .read),
(".algolia.net", .write),
].map(buildHost)

let commonHosts = try [
("-1.algolianet.com", .universal),
("-2.algolianet.com", .universal),
("-3.algolianet.com", .universal),
].map(buildHost).shuffled()

self.hosts = hosts + commonHosts
{{/hasRegionalHost}}{{/uniqueHost}}
{{#uniqueHost}}
guard let url = URL(string: "https://{{{.}}}") else {
throw AlgoliaError.runtimeError("Malformed URL")
}

self.hosts = [
.init(url: url)
]
{{#fallbackToAliasHost}}
} else {
guard let url = URL(string: "https://{{{hostWithFallback}}}") else {
throw AlgoliaError.runtimeError("Malformed URL")
self.hosts = [
.init(url: url)
]
{{/uniqueHost}}
{{#hasRegionalHost}}
guard {{#fallbackToAliasHost}}region == nil || {{/fallbackToAliasHost}}authorizedRegions.contains(region{{#fallbackToAliasHost}}!{{/fallbackToAliasHost}}) else {
throw AlgoliaError.runtimeError(
"`region` {{^fallbackToAliasHost}}is required and {{/fallbackToAliasHost}}must be one of the following: \(authorizedRegions.map { $0.rawValue }.joined(separator: ", "))"
)
}

self.hosts = [
.init(url: url)
]
}
{{/fallbackToAliasHost}}
{{/hasRegionalHost}}
{{#fallbackToAliasHost}}
if let region = region {
{{/fallbackToAliasHost}}
guard let url = URL(string: "https://{{{regionalHost}}}".replacingOccurrences(of: "{region}", with: region.rawValue)) else {
throw AlgoliaError.runtimeError("Malformed URL")
}

self.hosts = [
.init(url: url)
]
{{#fallbackToAliasHost}}
} else {
guard let url = URL(string: "https://{{{hostWithFallback}}}") else {
throw AlgoliaError.runtimeError("Malformed URL")
}

self.hosts = [
.init(url: url)
]
}
{{/fallbackToAliasHost}}
{{/hasRegionalHost}}
return
}

UserAgentController.append(UserAgent(title: "{{#lambda.client-to-name}}{{client}}{{/lambda.client-to-name}}", version: Version.current.description))
self.hosts = hosts
}
}

0 comments on commit 39c94cc

Please # to comment.