Skip to content

Commit 1dc38b4

Browse files
committed
new retry logic
1 parent 796ec2c commit 1dc38b4

File tree

4 files changed

+73
-75
lines changed

4 files changed

+73
-75
lines changed

AlgoliaSearch-Client-Swift.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = 'AlgoliaSearch-Client-Swift'
3-
s.version = '1.1.1'
3+
s.version = '1.2.0'
44
s.license = 'MIT'
55
s.summary = 'Algolia Search API Client for iOS & OS X written in Swift.'
66
s.homepage = 'https://github.com/algolia/algoliasearch-client-swift'

Source/Client.swift

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -56,28 +56,25 @@ public class Client {
5656
}
5757
}
5858

59-
public var timeout: NSTimeInterval = 30 {
60-
didSet {
61-
manager.session.configuration.timeoutIntervalForRequest = timeout;
62-
}
63-
}
59+
private let timeout: NSTimeInterval = 30
60+
private let searchTimeout: NSTimeInterval = 5
61+
private let incrementTimeout: NSTimeInterval = 10
6462

6563
public let appID: String
6664

67-
private var hostnames: [String]
65+
let readQueryHostnames: [String]
66+
let writeQueryHostnames: [String]
67+
6868
private let manager: Manager
6969
private var requestBuffer = RingBuffer<Request>(maxCapacity: 10)
7070

7171
/// Algolia Search initialization.
7272
///
7373
/// :param: appID the application ID you have in your admin interface
7474
/// :param: apiKey a valid API key for the service
75-
/// :param: hostnames the list of hosts that you have received for the service
76-
/// :param: dsn set to true if your account has the Distributed Search Option
77-
/// :param: dsnHost the host that you have received for the Distributed Search Option
7875
/// :param: tagFilters value of the header X-Algolia-TagFilters
7976
/// :param: userToken value of the header X-Algolia-UserToken
80-
public init(appID: String, apiKey: String, hostnames: [String]? = nil, dsn: Bool = false, dsnHost: String? = nil, tagFilters: String? = nil, userToken: String? = nil) {
77+
public init(appID: String, apiKey: String, tagFilters: String? = nil, userToken: String? = nil) {
8178
if count(appID) == 0 {
8279
NSException(name: "InvalidArgument", reason: "Application ID must be set", userInfo: nil).raise()
8380
} else if count(apiKey) == 0 {
@@ -89,24 +86,19 @@ public class Client {
8986
self.tagFilters = tagFilters
9087
self.userToken = userToken
9188

92-
if (hostnames == nil || hostnames!.count == 0) {
93-
var generateHostname = [String]()
94-
for i in 1...3 {
95-
generateHostname.append("\(appID)-\(i).algolia.net")
96-
}
97-
self.hostnames = generateHostname
98-
} else {
99-
self.hostnames = hostnames!
100-
}
101-
self.hostnames.shuffle()
89+
readQueryHostnames = [
90+
"\(appID)-DSN.algolia.net",
91+
"\(appID)-1.algolianet.com",
92+
"\(appID)-2.algolianet.com",
93+
"\(appID)-3.algolianet.com"
94+
]
10295

103-
if dsn {
104-
if let dsnHost = dsnHost {
105-
self.hostnames.insert(dsnHost, atIndex: 0)
106-
} else {
107-
self.hostnames.insert("\(appID)-dsn.algolia.net", atIndex: 0)
108-
}
109-
}
96+
writeQueryHostnames = [
97+
"\(appID).algolia.net",
98+
"\(appID)-1.algolianet.com",
99+
"\(appID)-2.algolianet.com",
100+
"\(appID)-3.algolianet.com"
101+
]
110102

111103
let version = NSBundle(identifier: "com.algolia.AlgoliaSearch")!.infoDictionary!["CFBundleShortVersionString"] as! String
112104
var HTTPHeaders = [
@@ -144,7 +136,7 @@ public class Client {
144136
///
145137
/// :return: JSON Object in the handler in the form: { "items": [ {"name": "contacts", "createdAt": "2013-01-18T15:33:13.556Z"}, {"name": "notes", "createdAt": "2013-01-18T15:33:13.556Z"}]}
146138
public func listIndexes(block: CompletionHandler) {
147-
performHTTPQuery("1/indexes", method: .GET, body: nil, block: block)
139+
performHTTPQuery("1/indexes", method: .GET, body: nil, hostnames: readQueryHostnames, block: block)
148140
}
149141

150142
/// Delete an index.
@@ -153,7 +145,7 @@ public class Client {
153145
/// :return: JSON Object in the handler containing a "deletedAt" attribute
154146
public func deleteIndex(indexName: String, block: CompletionHandler? = nil) {
155147
let path = "1/indexes/\(indexName.urlEncode())"
156-
performHTTPQuery(path, method: .DELETE, body: nil, block: block)
148+
performHTTPQuery(path, method: .DELETE, body: nil, hostnames: writeQueryHostnames, block: block)
157149
}
158150

159151
/// Move an existing index.
@@ -167,7 +159,7 @@ public class Client {
167159
"operation": "move"
168160
]
169161

170-
performHTTPQuery(path, method: .POST, body: request, block: block)
162+
performHTTPQuery(path, method: .POST, body: request, hostnames: writeQueryHostnames, block: block)
171163
}
172164

173165
/// Copy an existing index.
@@ -181,12 +173,12 @@ public class Client {
181173
"operation": "copy"
182174
]
183175

184-
performHTTPQuery(path, method: .POST, body: request, block: block)
176+
performHTTPQuery(path, method: .POST, body: request, hostnames: writeQueryHostnames, block: block)
185177
}
186178

187179
/// Return 10 last log entries.
188180
public func getLogs(block: CompletionHandler) {
189-
performHTTPQuery("1/logs", method: .GET, body: nil, block: block)
181+
performHTTPQuery("1/logs", method: .GET, body: nil, hostnames: readQueryHostnames, block: block)
190182
}
191183

192184
/// Return last logs entries.
@@ -195,7 +187,7 @@ public class Client {
195187
/// :param: length Specify the maximum number of entries to retrieve starting at offset. Maximum allowed value: 1000.
196188
public func getLogsWithOffset(offset: UInt, length: UInt, block: CompletionHandler) {
197189
let path = "1/logs?offset=\(offset)&length=\(length)"
198-
performHTTPQuery(path, method: .GET, body: nil, block: block)
190+
performHTTPQuery(path, method: .GET, body: nil, hostnames: readQueryHostnames, block: block)
199191
}
200192

201193
/// Return last logs entries.
@@ -204,7 +196,7 @@ public class Client {
204196
/// :param: length Specify the maximum number of entries to retrieve starting at offset. Maximum allowed value: 1000.
205197
public func getLogsWithType(type: String, offset: UInt, length: UInt, block: CompletionHandler) {
206198
let path = "1/logs?offset=\(offset)&length=\(length)&type=\(type)"
207-
performHTTPQuery(path, method: .GET, body: nil, block: block)
199+
performHTTPQuery(path, method: .GET, body: nil, hostnames: readQueryHostnames, block: block)
208200
}
209201

210202
/// Get the index object initialized (no server call needed for initialization).
@@ -216,27 +208,27 @@ public class Client {
216208

217209
/// List all existing user keys with their associated ACLs.
218210
public func listUserKeys(block: CompletionHandler) {
219-
performHTTPQuery("1/keys", method: .GET, body: nil, block: block)
211+
performHTTPQuery("1/keys", method: .GET, body: nil, hostnames: readQueryHostnames, block: block)
220212
}
221213

222214
/// Get ACL of a user key.
223215
public func getUserKeyACL(key: String, block: CompletionHandler) {
224216
let path = "1/keys/\(key)"
225-
performHTTPQuery(path, method: .GET, body: nil, block: block)
217+
performHTTPQuery(path, method: .GET, body: nil, hostnames: readQueryHostnames, block: block)
226218
}
227219

228220
/// Delete an existing user key.
229221
public func deleteUserKey(key: String, block: CompletionHandler? = nil) {
230222
let path = "1/keys/\(key)"
231-
performHTTPQuery(path, method: .DELETE, body: nil, block: block)
223+
performHTTPQuery(path, method: .DELETE, body: nil, hostnames: writeQueryHostnames, block: block)
232224
}
233225

234226
/// Create a new user key
235227
///
236228
/// :param: acls The list of ACL for this key. The list can contains the following values (as String): search, addObject, deleteObject, deleteIndex, settings, editSettings
237229
public func addUserKey(acls: [String], block: CompletionHandler? = nil) {
238230
let request = ["acl": acls]
239-
performHTTPQuery("1/keys", method: .POST, body: request, block: block)
231+
performHTTPQuery("1/keys", method: .POST, body: request, hostnames: writeQueryHostnames, block: block)
240232
}
241233

242234
/// Create a new user key
@@ -253,7 +245,7 @@ public class Client {
253245
"maxHitsPerQuery": maxHits,
254246
]
255247

256-
performHTTPQuery("1/keys", method: .POST, body: request, block: block)
248+
performHTTPQuery("1/keys", method: .POST, body: request, hostnames: writeQueryHostnames, block: block)
257249
}
258250

259251
/// Create a new user key
@@ -272,7 +264,7 @@ public class Client {
272264
"maxHitsPerQuery": maxHits,
273265
]
274266

275-
performHTTPQuery("1/keys", method: .POST, body: request, block: block)
267+
performHTTPQuery("1/keys", method: .POST, body: request, hostnames: writeQueryHostnames, block: block)
276268
}
277269

278270
/// Update a user key
@@ -282,7 +274,7 @@ public class Client {
282274
public func updateUserKey(key: String, withACL acls: [String], block: CompletionHandler? = nil) {
283275
let path = "1/keys/\(key)"
284276
let request = ["acl": acls]
285-
performHTTPQuery(path, method: .PUT, body: request, block: block)
277+
performHTTPQuery(path, method: .PUT, body: request, hostnames: writeQueryHostnames, block: block)
286278
}
287279

288280
/// Update a user key
@@ -301,7 +293,7 @@ public class Client {
301293
"maxHitsPerQuery": maxHits,
302294
]
303295

304-
performHTTPQuery(path, method: .PUT, body: request, block: block)
296+
performHTTPQuery(path, method: .PUT, body: request, hostnames: writeQueryHostnames, block: block)
305297
}
306298

307299
/// Update a user key
@@ -322,7 +314,7 @@ public class Client {
322314
"maxHitsPerQuery": maxHits,
323315
]
324316

325-
performHTTPQuery(path, method: .PUT, body: request, block: block)
317+
performHTTPQuery(path, method: .PUT, body: request, hostnames: writeQueryHostnames, block: block)
326318
}
327319

328320
/// Query multiple indexes with one API call.
@@ -343,20 +335,26 @@ public class Client {
343335
}
344336

345337
let request = ["requests": convertedQueries]
346-
performHTTPQuery(path, method: .POST, body: request, block: block)
338+
performHTTPQuery(path, method: .POST, body: request, hostnames: readQueryHostnames, block: block)
347339
}
348340

349341
// MARK: - Network
350342

351343
/// Perform an HTTP Query.
352-
func performHTTPQuery(path: String, method: HTTPMethod, body: [String: AnyObject]?, index: Int = 0, block: CompletionHandler? = nil) {
344+
func performHTTPQuery(path: String, method: HTTPMethod, body: [String: AnyObject]?, hostnames: [String], isSearchQuery: Bool = false, index: Int = 0, block: CompletionHandler? = nil) {
353345
assert(index < hostnames.count, "\(index) < \(hostnames.count) !")
354346

347+
var currentTimeout = (isSearchQuery) ? searchTimeout : timeout
348+
if index > 1 {
349+
currentTimeout += incrementTimeout
350+
}
351+
manager.session.configuration.timeoutIntervalForRequest = currentTimeout
352+
355353
let request = manager.request(method, "https://\(hostnames[index])/\(path)", parameters: body) { (response, data, error) -> Void in
356354
if let statusCode = response?.statusCode {
357355
if let block = block {
358356
switch(statusCode) {
359-
case 200, 201:
357+
case 200..<300:
360358
block(JSON: (data as! [String: AnyObject]), error: nil)
361359
case 400:
362360
let errorMessage = data!["message"] as! String
@@ -374,8 +372,8 @@ public class Client {
374372
}
375373
}
376374
} else {
377-
if (index + 1) < self.hostnames.count {
378-
self.performHTTPQuery(path, method: method, body: body, index: index + 1, block: block)
375+
if (index + 1) < hostnames.count {
376+
self.performHTTPQuery(path, method: method, body: body, hostnames: hostnames, isSearchQuery: isSearchQuery, index: index + 1, block: block)
379377
} else {
380378
block?(JSON: nil, error: error)
381379
}

0 commit comments

Comments
 (0)