Remove snodes from a swarm if they failed repeatedly

pull/33/head
Niels Andriesse 6 years ago
parent 02dd81516b
commit f32bb85ddc

@ -4,10 +4,12 @@ extension String : Error { }
public extension LokiAPI { public extension LokiAPI {
fileprivate static var failureCount: [LokiAPITarget:UInt] = [:]
// MARK: Settings // MARK: Settings
private static let minimumSnodeCount = 2 private static let minimumSnodeCount = 2
private static let targetSnodeCount = 3 private static let targetSnodeCount = 3
private static let defaultSnodePort: UInt16 = 8080 fileprivate static let failureThreshold = 3
// MARK: Caching // MARK: Caching
private static let swarmCacheKey = "swarmCacheKey" private static let swarmCacheKey = "swarmCacheKey"
@ -100,8 +102,15 @@ internal extension Promise {
if let error = error as? NetworkManagerError { if let error = error as? NetworkManagerError {
switch error.statusCode { switch error.statusCode {
case 0: case 0:
// The snode is unreachable; usually a problem with LokiNet // The snode is unreachable
print("[Loki] Couldn't reach snode at: \(target.address):\(target.port).") let oldFailureCount = LokiAPI.failureCount[target] ?? 0
let newFailureCount = oldFailureCount + 1
LokiAPI.failureCount[target] = newFailureCount
print("[Loki] Couldn't reach snode at: \(target.address):\(target.port); setting failure count to: \(newFailureCount).")
if oldFailureCount >= LokiAPI.failureThreshold {
print("[Loki] Failure threshold reached for: \(target); removing it from the swarm cache for: \(hexEncodedPublicKey).")
LokiAPI.dropIfNeeded(target, hexEncodedPublicKey: hexEncodedPublicKey)
}
case 421: case 421:
// The snode isn't associated with the given public key anymore // The snode isn't associated with the given public key anymore
print("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).") print("[Loki] Invalidating swarm for: \(hexEncodedPublicKey).")

@ -44,14 +44,8 @@ public final class LokiAPI : NSObject {
if let headers = headers { request.allHTTPHeaderFields = headers } if let headers = headers { request.allHTTPHeaderFields = headers }
if let timeout = timeout { request.timeoutInterval = timeout ?? defaultTimeout } if let timeout = timeout { request.timeoutInterval = timeout ?? defaultTimeout }
let headers = request.allHTTPHeaderFields ?? [:] let headers = request.allHTTPHeaderFields ?? [:]
let headersDescription = headers.isEmpty ? "no custom headers specified" : headers.description let headersDescription = headers.isEmpty ? "no custom headers specified" : headers.prettifiedDescription
let parametersDescription = "[ " + parameters.map { key, value in print("[Loki] Invoking \(method.rawValue) on \(target) with \(parameters.prettifiedDescription) (\(headersDescription)).")
let valueDescription = String(describing: value)
let maxLength = 20
let truncatedValueDescription = valueDescription.count > maxLength ? valueDescription.prefix(maxLength) + "..." : valueDescription
return key + " : " + truncatedValueDescription
}.joined(separator: ", ") + " ]"
print("[Loki] Invoking \(method.rawValue) on \(target) with \(parametersDescription) (\(headersDescription)).")
return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject } return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }
.handlingSwarmSpecificErrorsIfNeeded(for: target, associatedWith: hexEncodedPublicKey).recoveringNetworkErrorsIfNeeded() .handlingSwarmSpecificErrorsIfNeeded(for: target, associatedWith: hexEncodedPublicKey).recoveringNetworkErrorsIfNeeded()
} }

@ -0,0 +1,13 @@
public extension Dictionary {
public var prettifiedDescription: String {
return "[ " + map { key, value in
let keyDescription = String(describing: key)
let valueDescription = String(describing: value)
let maxLength = 20
let truncatedValueDescription = valueDescription.count > maxLength ? valueDescription.prefix(maxLength) + "..." : valueDescription
return keyDescription + " : " + truncatedValueDescription
}.joined(separator: ", ") + " ]"
}
}

@ -1186,7 +1186,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
}) retainUntilComplete]; }) retainUntilComplete];
} }
}) })
.catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // Unreachable snode; usually a problem with LokiNet .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { // The snode is unreachable
handleError(error); handleError(error);
}) retainUntilComplete]; }) retainUntilComplete];

Loading…
Cancel
Save