-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathMPTransportErrorDetector.swift
More file actions
78 lines (67 loc) · 2.71 KB
/
MPTransportErrorDetector.swift
File metadata and controls
78 lines (67 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import Foundation
@objc public class MPTransportErrorDetector: NSObject {
private static let maxRetryAfter: Double = 300
private static let maxErrorCountBeforeMaxRetry = 5
private static let retryAfterSchedule: [Double] = [5, 15, 60, 120, 300]
private static var consecutiveTransportErrorCount = 0
private static let backoffQueue = DispatchQueue(label: "com.mparticle.transport-error-backoff")
private static let semaphoreTimeoutErrorDomainValue = "com.mparticle"
private static let semaphoreTimeoutErrorCodeValue = 0
@objc(semaphoreTimeoutErrorDomain)
public static func semaphoreTimeoutErrorDomain() -> NSString {
semaphoreTimeoutErrorDomainValue as NSString
}
@objc(semaphoreTimeoutErrorCode)
public static func semaphoreTimeoutErrorCode() -> NSNumber {
NSNumber(value: semaphoreTimeoutErrorCodeValue)
}
@objc(isRetriableTransportError:)
public static func isRetriableTransportError(_ error: NSError?) -> Bool {
guard let error else {
return false
}
if error.domain == NSURLErrorDomain {
switch error.code {
case NSURLErrorCannotFindHost,
NSURLErrorCannotConnectToHost,
NSURLErrorNotConnectedToInternet,
NSURLErrorNetworkConnectionLost,
NSURLErrorDNSLookupFailed,
NSURLErrorTimedOut,
NSURLErrorCannotLoadFromNetwork,
NSURLErrorSecureConnectionFailed,
NSURLErrorInternationalRoamingOff,
NSURLErrorDataNotAllowed,
NSURLErrorCallIsActive:
return true
default:
return false
}
}
return error.domain == semaphoreTimeoutErrorDomainValue
&& error.code == semaphoreTimeoutErrorCodeValue
}
@objc(calculateRetryTimeForTransportError)
public static func calculateRetryTimeForTransportError() -> NSNumber {
return backoffQueue.sync {
consecutiveTransportErrorCount += 1
if consecutiveTransportErrorCount >= maxErrorCountBeforeMaxRetry {
return NSNumber(value: maxRetryAfter)
}
guard !retryAfterSchedule.isEmpty else {
return NSNumber(value: maxRetryAfter)
}
let scheduleIndex = min(
max(0, consecutiveTransportErrorCount - 1),
retryAfterSchedule.count - 1
)
return NSNumber(value: retryAfterSchedule[scheduleIndex])
}
}
@objc(resetTransportErrorCounter)
public static func resetTransportErrorCounter() {
backoffQueue.sync {
consecutiveTransportErrorCount = 0
}
}
}