From e1d2c48c9b7acd7f76ed66f37947f38166f29e80 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 22 May 2019 12:24:20 +1000 Subject: [PATCH] Integrate swarm changes into message sending code --- SignalServiceKit/src/Loki/API/LokiAPI.swift | 6 +- .../src/Messages/OWSMessageSender.m | 94 ++++++++++--------- 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index a841c4dae..f3108ce50 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -91,7 +91,11 @@ import PromiseKit // MARK: Public API (Obj-C) @objc public static func objc_sendSignalMessage(_ signalMessage: SignalMessage, to destination: String, timestamp: UInt64, requiringPoW isPoWRequired: Bool) -> AnyPromise { - let promise = Message.from(signalMessage: signalMessage, timestamp: timestamp, requiringPoW: isPoWRequired).then(sendMessage) + let promise = Message.from(signalMessage: signalMessage, timestamp: timestamp, requiringPoW: isPoWRequired).then(sendMessage).mapValues { promise -> AnyPromise in + let anyPromise = AnyPromise(promise) + anyPromise.retainUntilComplete() + return anyPromise + }.map { Set($0) } let anyPromise = AnyPromise(promise) anyPromise.retainUntilComplete() return anyPromise diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 419102baa..3b00e5484 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1103,11 +1103,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; return messageSend.failure(error); } - // Update the state to show that proof of work is being calculated + // Update the state to show that the proof of work is being calculated [self setIsCalculatingProofOfWorkForMessage:messageSend]; // Convert the message to a Loki message and send it using the Loki messaging API NSDictionary *signalMessage = deviceMessages.firstObject; - // Update the thread's friend request status if needed + // Update the message and thread if needed NSInteger *messageType = ((NSNumber *)signalMessage[@"type"]).integerValue; if (messageType == TSFriendRequestMessageType) { [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSending withTransaction:nil]; @@ -1116,51 +1116,53 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; BOOL isPoWRequired = YES; // TODO: Base on message type [[LokiAPI objc_sendSignalMessage:signalMessage to:recipient.recipientId timestamp:message.timestamp requiringPoW:isPoWRequired] .thenOn(OWSDispatch.sendingQueue, ^(id result) { - // Loki - // ======== - if (messageType == TSFriendRequestMessageType) { - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSent withTransaction:transaction]; - [message.thread removeOutgoingFriendRequestMessagesWithTransaction:transaction]; - // Set the expiration date - NSTimeInterval expirationInterval = 72 * kHourInterval; - NSDate *expireDate = [[NSDate new] dateByAddingTimeInterval:expirationInterval]; - [message saveFriendRequestExpiresAt:[NSDate ows_millisecondsSince1970ForDate:expireDate] withTransaction:transaction]; - }]; - } - // ======== - // Invoke the completion handler - [self messageSendDidSucceed:messageSend - deviceMessages:deviceMessages - wasSentByUD:false - wasSentByWebsocket:false]; - }) - .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { - // Loki - // ======== - if (messageType == TSFriendRequestMessageType) { - [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusNone withTransaction:nil]; - } - // ======== - // Handle the error - NSUInteger statusCode = 0; - NSData *_Nullable responseData = nil; - if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) { - statusCode = error.code; - NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey]; - if (underlyingError) { - responseData = underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey]; - } else { - OWSFailDebug(@"Missing underlying error: %@", error); - } - } else { - OWSFailDebug(@"Unexpected error: %@", error); + NSSet *promises = (NSSet *)result; + BOOL isSuccess = NO; + NSUInteger promiseCount = promises.count; + NSUInteger errorCount = 0; + for (AnyPromise *promise in promises) { + [promise + .thenOn(OWSDispatch.sendingQueue, ^(id result) { + if (isSuccess) { return; } // Succeed as soon as the first promise succeeds + isSuccess = YES; + // Update the message and thread if needed + if (messageType == TSFriendRequestMessageType) { + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusRequestSent withTransaction:transaction]; + [message.thread removeOutgoingFriendRequestMessagesWithTransaction:transaction]; + NSTimeInterval expirationInterval = 72 * kHourInterval; + NSDate *expirationDate = [[NSDate new] dateByAddingTimeInterval:expirationInterval]; + [message saveFriendRequestExpiresAt:[NSDate ows_millisecondsSince1970ForDate:expirationDate] withTransaction:transaction]; + }]; + } + // Invoke the completion handler + [self messageSendDidSucceed:messageSend deviceMessages:deviceMessages wasSentByUD:false wasSentByWebsocket:false]; + }) + .catchOn(OWSDispatch.sendingQueue, ^(NSError *error) { + errorCount += 1; + if (errorCount != promiseCount) { return; } // Only error out if all promises failed + // Update the thread if needed + if (messageType == TSFriendRequestMessageType) { + [message.thread saveFriendRequestStatus:TSThreadFriendRequestStatusNone withTransaction:nil]; + } + // Handle the error + NSUInteger statusCode = 0; + NSData *_Nullable responseData = nil; + if ([error.domain isEqualToString:TSNetworkManagerErrorDomain]) { + statusCode = error.code; + NSError *_Nullable underlyingError = error.userInfo[NSUnderlyingErrorKey]; + if (underlyingError) { + responseData = underlyingError.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey]; + } else { + OWSFailDebug(@"Missing underlying error: %@.", error); + } + } else { + OWSFailDebug(@"Unexpected error: %@.", error); + } + [self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData]; + }) retainUntilComplete]; } - [self messageSendDidFail:messageSend - deviceMessages:deviceMessages - statusCode:statusCode - error:error - responseData:responseData]; + }) retainUntilComplete]; // Loki: Original code