Skip to content

Commit c0868f6

Browse files
author
Clément Le Provost
committed
Shuffle host array at client init
Fixes #56.
1 parent feb1660 commit c0868f6

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

Source/Client.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,20 @@ import Foundation
100100
self.apiKey = apiKey
101101

102102
// Initialize hosts to their default values.
103-
readHosts = [
104-
"\(appID)-dsn.algolia.net",
103+
//
104+
// NOTE: The host list comes in two parts:
105+
//
106+
// 1. The fault-tolerant, load-balanced DNS host.
107+
// 2. The non-fault-tolerant hosts. Those hosts must be randomized to ensure proper load balancing in case
108+
// of the first host's failure.
109+
//
110+
let fallbackHosts = [
105111
"\(appID)-1.algolianet.com",
106112
"\(appID)-2.algolianet.com",
107113
"\(appID)-3.algolianet.com"
108-
]
109-
writeHosts = [
110-
"\(appID).algolia.net",
111-
"\(appID)-1.algolianet.com",
112-
"\(appID)-2.algolianet.com",
113-
"\(appID)-3.algolianet.com"
114-
]
114+
].shuffle()
115+
readHosts = [ "\(appID)-dsn.algolia.net" ] + fallbackHosts
116+
writeHosts = [ "\(appID).algolia.net" ] + fallbackHosts
115117

116118
// WARNING: Those headers cannot be changed for the lifetime of the session.
117119
let version = NSBundle(forClass: self.dynamicType).infoDictionary!["CFBundleShortVersionString"] as! String

Source/Helpers.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,29 @@ extension String {
2929
let customAllowedSet = NSCharacterSet(charactersInString: "!*'();:@&=+$,/?%#[]").invertedSet
3030
return stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)!
3131
}
32-
}
32+
}
33+
34+
// Collection shuffling taken from <http://stackoverflow.com/questions/24026510/how-do-i-shuffle-an-array-in-swift>.
35+
36+
extension CollectionType {
37+
/// Return a copy of `self` with its elements shuffled.
38+
func shuffle() -> [Generator.Element] {
39+
var list = Array(self)
40+
list.shuffleInPlace()
41+
return list
42+
}
43+
}
44+
45+
extension MutableCollectionType where Index == Int {
46+
/// Shuffle the elements of `self` in-place.
47+
mutating func shuffleInPlace() {
48+
// Empty and single-element collections don't shuffle.
49+
if count < 2 { return }
50+
51+
for i in 0..<count - 1 {
52+
let j = Int(arc4random_uniform(UInt32(count - i))) + i
53+
guard i != j else { continue }
54+
swap(&self[i], &self[j])
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)