restore PreKey upload failure tracking

pull/1/head
Michael Kirk 6 years ago
parent 39b691b697
commit 85d35b52d6

@ -80,6 +80,7 @@ public class RotateSignedPreKeyOperation: OWSOperation {
self.primaryStorage.storeSignedPreKey(signedPreKeyRecord.id, signedPreKeyRecord: signedPreKeyRecord)
self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id)
TSPreKeyManager.clearPreKeyUpdateFailureCount()
TSPreKeyManager.clearSignedPreKeyRecords()
}.then { () -> Void in
Logger.debug("done")
@ -88,6 +89,25 @@ public class RotateSignedPreKeyOperation: OWSOperation {
self.reportError(error)
}.retainUntilComplete()
}
override public func didFail(error: Error) {
switch error {
case let networkManagerError as NetworkManagerError:
guard !networkManagerError.isNetworkError else {
Logger.debug("don't report SPK rotation failure w/ network error")
return
}
guard networkManagerError.statusCode >= 400 && networkManagerError.statusCode <= 599 else {
Logger.debug("don't report SPK rotation failure w/ non application error")
return
}
TSPreKeyManager.incrementPreKeyUpdateFailureCount()
default:
Logger.debug("don't report SPK rotation failure w/ non NetworkManager error: \(error)")
}
}
}
@objc(SSKRefreshPreKeysOperation)
@ -136,6 +156,7 @@ public class RefreshPreKeysOperation: OWSOperation {
self.primaryStorage.setCurrentSignedPrekeyId(signedPreKeyRecord.id)
self.primaryStorage.storePreKeyRecords(preKeyRecords)
TSPreKeyManager.clearPreKeyUpdateFailureCount()
TSPreKeyManager.clearSignedPreKeyRecords()
}
}.then { () -> Void in
@ -145,4 +166,23 @@ public class RefreshPreKeysOperation: OWSOperation {
self.reportError(error)
}.retainUntilComplete()
}
override public func didFail(error: Error) {
switch error {
case let networkManagerError as NetworkManagerError:
guard !networkManagerError.isNetworkError else {
Logger.debug("don't report SPK rotation failure w/ network error")
return
}
guard networkManagerError.statusCode >= 400 && networkManagerError.statusCode <= 599 else {
Logger.debug("don't report SPK rotation failure w/ non application error")
return
}
TSPreKeyManager.incrementPreKeyUpdateFailureCount()
default:
Logger.debug("don't report SPK rotation failure w/ non NetworkManager error: \(error)")
}
}
}

@ -19,8 +19,18 @@ typedef NS_ENUM(NSInteger, RefreshPreKeysMode) {
@interface TSPreKeyManager : NSObject
#pragma mark - State Tracking
+ (BOOL)isAppLockedDueToPreKeyUpdateFailures;
+ (void)incrementPreKeyUpdateFailureCount;
+ (void)clearPreKeyUpdateFailureCount;
+ (void)clearSignedPreKeyRecords;
#pragma mark - Check/Request Initiation
+ (void)rotateSignedPreKeyWithSuccess:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler;
+ (void)createPreKeysWithSuccess:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler;
@ -28,6 +38,5 @@ typedef NS_ENUM(NSInteger, RefreshPreKeysMode) {
+ (void)checkPreKeys;
+ (void)checkPreKeysIfNecessary;
+ (void)clearSignedPreKeyRecordsWithKeyId:(NSNumber *)keyId;
@end

@ -37,6 +37,8 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5;
@implementation TSPreKeyManager
#pragma mark - State Tracking
+ (BOOL)isAppLockedDueToPreKeyUpdateFailures
{
// Only disable message sending if we have failed more than N times
@ -53,6 +55,8 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5;
// Record a prekey update failure.
OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager];
int failureCount = [primaryStorage incrementPrekeyUpdateFailureCount];
OWSLogInfo(@"new failureCount: %d", failureCount);
if (failureCount == 1 || ![primaryStorage firstPrekeyUpdateFailureDate]) {
// If this is the "first" failure, record the timestamp of that
// failure.
@ -67,6 +71,8 @@ static const NSUInteger kMaxPrekeyUpdateFailureCount = 5;
[primaryStorage clearPrekeyUpdateFailureCount];
}
#pragma mark - Check/Request Initiation
+ (NSOperationQueue *)operationQueue
{
static dispatch_once_t onceToken;

@ -0,0 +1,46 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
import Foundation
import PromiseKit
enum NetworkManagerError: Error {
/// Wraps TSNetworkManager failure callback params in a single throwable error
case taskError(task: URLSessionDataTask, underlyingError: Error)
}
extension NetworkManagerError {
var isNetworkError: Bool {
switch self {
case .taskError(_, let underlyingError):
return IsNSErrorNetworkFailure(underlyingError)
}
}
var statusCode: Int {
switch self {
case .taskError(let task, _):
return task.statusCode()
}
}
}
extension TSNetworkManager {
func makePromise(request: TSRequest) -> Promise<(task: URLSessionDataTask, responseObject: Any?)> {
let (promise, fulfill, reject) = Promise<(task: URLSessionDataTask, responseObject: Any?)>.pending()
self.makeRequest(request,
success: { task, responseObject in
fulfill((task: task, responseObject: responseObject))
},
failure: { task, error in
let nmError = NetworkManagerError.taskError(task: task, underlyingError: error)
let nsError: NSError = nmError as NSError
nsError.isRetryable = (error as NSError).isRetryable
reject(nsError)
})
return promise
}
}

@ -24,67 +24,30 @@ class ServiceRestSocket: ServiceSocket {
func getAvailablePreKeys() -> Promise<Int> {
Logger.debug("")
let (promise, fulfill, reject) = Promise<Int>.pending()
let request = OWSRequestFactory.availablePreKeysCountRequest()
networkManager.makeRequest(request,
success: { (_, responseObject) in
Logger.debug("got response")
guard let params = ParamParser(responseObject: responseObject) else {
reject(self.unexpectedServerResponseError())
return
}
return networkManager.makePromise(request: request).then { (_, responseObject) -> Int in
Logger.debug("got response")
guard let params = ParamParser(responseObject: responseObject) else {
throw self.unexpectedServerResponseError()
}
let count: Int
do {
count = try params.required(key: "count")
} catch {
reject(error)
return
}
let count: Int = try! params.required(key: "count")
fulfill(count)
},
failure: { (_, error) in
Logger.debug("error: \(error)")
reject(error)
})
return promise
return count
}
}
func registerPreKeys(identityKey: IdentityKey, signedPreKeyRecord: SignedPreKeyRecord, preKeyRecords: [PreKeyRecord]) -> Promise<Void> {
Logger.debug("")
let (promise, fulfill, reject) = Promise<Void>.pending()
let request = OWSRequestFactory.registerPrekeysRequest(withPrekeyArray: preKeyRecords, identityKey: identityKey, signedPreKey: signedPreKeyRecord)
networkManager.makeRequest(request,
success: { (_, _) in
Logger.debug("success")
fulfill(())
},
failure: { (_, error) in
Logger.debug("error: \(error)")
reject(error)
})
return promise
return networkManager.makePromise(request: request).asVoid()
}
public func setCurrentSignedPreKey(_ signedPreKey: SignedPreKeyRecord) -> Promise<Void> {
let (promise, fulfill, reject) = Promise<Void>.pending()
let request = OWSRequestFactory.registerSignedPrekeyRequest(with: signedPreKey)
networkManager.makeRequest(request,
success: { (_, _) in
Logger.debug("success")
fulfill(())
Logger.debug("")
},
failure: { (_, error) in
Logger.debug("error: \(error)")
reject(error)
})
return promise
let request = OWSRequestFactory.registerSignedPrekeyRequest(with: signedPreKey)
return networkManager.makePromise(request: request).asVoid()
}
}

Loading…
Cancel
Save