|
|
|
@ -155,7 +155,7 @@ NSUInteger const OWSSendMessageOperationMaxRetries = 4;
|
|
|
|
|
|
|
|
|
|
@property (nonatomic, readonly) TSOutgoingMessage *message;
|
|
|
|
|
@property (nonatomic, readonly) OWSMessageSender *messageSender;
|
|
|
|
|
@property (nonatomic, readonly) void (^successHandler)();
|
|
|
|
|
@property (nonatomic, readonly) void (^successHandler)(void);
|
|
|
|
|
@property (nonatomic, readonly) void (^failureHandler)(NSError *_Nonnull error);
|
|
|
|
|
@property (nonatomic) OWSSendMessageOperationState operationState;
|
|
|
|
|
@property (nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;
|
|
|
|
@ -190,12 +190,7 @@ NSUInteger const OWSSendMessageOperationMaxRetries = 4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update the message unless it has been deleted.
|
|
|
|
|
if ([TSOutgoingMessage fetchObjectWithUniqueID:message.uniqueId]) {
|
|
|
|
|
[message updateWithMessageState:TSOutgoingMessageStateSentToService];
|
|
|
|
|
} else {
|
|
|
|
|
DDLogInfo(@"%@ not marking message sent; message deleted.", strongSelf.logTag);
|
|
|
|
|
}
|
|
|
|
|
[message updateWithMessageState:TSOutgoingMessageStateSentToService];
|
|
|
|
|
|
|
|
|
|
aSuccessHandler();
|
|
|
|
|
|
|
|
|
@ -209,12 +204,7 @@ NSUInteger const OWSSendMessageOperationMaxRetries = 4;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update the message unless it has been deleted.
|
|
|
|
|
if ([TSOutgoingMessage fetchObjectWithUniqueID:message.uniqueId]) {
|
|
|
|
|
[strongSelf.message updateWithSendingError:error];
|
|
|
|
|
} else {
|
|
|
|
|
DDLogInfo(@"%@ not marking message failed; message deleted.", strongSelf.logTag);
|
|
|
|
|
}
|
|
|
|
|
[strongSelf.message updateWithSendingError:error];
|
|
|
|
|
|
|
|
|
|
DDLogDebug(@"%@ failed with error: %@", strongSelf.logTag, error);
|
|
|
|
|
aFailureHandler(error);
|
|
|
|
@ -429,9 +419,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)sendMessage:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(void (^)(NSError *error))failureHandler
|
|
|
|
|
- (void)enqueueOutgoingMessage:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(void (^)(NSError *error))failureHandler
|
|
|
|
|
{
|
|
|
|
|
OWSAssert(message);
|
|
|
|
|
|
|
|
|
@ -448,7 +438,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
//
|
|
|
|
|
// So we're using YDB behavior to ensure this invariant, which is a bit
|
|
|
|
|
// unorthodox.
|
|
|
|
|
[message updateWithMessageState:TSOutgoingMessageStateAttemptingOut];
|
|
|
|
|
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
|
// All outgoing messages should be saved at the time they are enqueued.
|
|
|
|
|
[message saveWithTransaction:transaction];
|
|
|
|
|
[message updateWithMessageState:TSOutgoingMessageStateAttemptingOut transaction:transaction];
|
|
|
|
|
}];
|
|
|
|
|
|
|
|
|
|
OWSSendMessageOperation *sendMessageOperation =
|
|
|
|
|
[[OWSSendMessageOperation alloc] initWithMessage:message
|
|
|
|
@ -476,12 +470,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
{
|
|
|
|
|
[self ensureAnyAttachmentsUploaded:message
|
|
|
|
|
success:^() {
|
|
|
|
|
[self deliverMessage:message
|
|
|
|
|
success:successHandler
|
|
|
|
|
failure:^(NSError *error) {
|
|
|
|
|
DDLogDebug(@"%@ Message send attempt failed: %@", self.logTag, message.debugDescription);
|
|
|
|
|
failureHandler(error);
|
|
|
|
|
}];
|
|
|
|
|
[self sendMessageToService:message
|
|
|
|
|
success:successHandler
|
|
|
|
|
failure:^(NSError *error) {
|
|
|
|
|
DDLogDebug(
|
|
|
|
|
@"%@ Message send attempt failed: %@", self.logTag, message.debugDescription);
|
|
|
|
|
failureHandler(error);
|
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
failure:^(NSError *error) {
|
|
|
|
|
DDLogDebug(@"%@ Attachment upload attempt failed: %@", self.logTag, message.debugDescription);
|
|
|
|
@ -514,15 +509,15 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
failure:failureHandler];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)sendTemporaryAttachmentData:(DataSource *)dataSource
|
|
|
|
|
contentType:(NSString *)contentType
|
|
|
|
|
inMessage:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(void (^)(NSError *error))failureHandler
|
|
|
|
|
- (void)enqueueOutgoingTemporaryAttachment:(DataSource *)dataSource
|
|
|
|
|
contentType:(NSString *)contentType
|
|
|
|
|
inMessage:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(void (^)(NSError *error))failureHandler
|
|
|
|
|
{
|
|
|
|
|
OWSAssert(dataSource);
|
|
|
|
|
|
|
|
|
|
void (^successWithDeleteHandler)() = ^() {
|
|
|
|
|
void (^successWithDeleteHandler)(void) = ^() {
|
|
|
|
|
successHandler();
|
|
|
|
|
|
|
|
|
|
DDLogDebug(@"Removing temporary attachment message.");
|
|
|
|
@ -536,20 +531,20 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
[message remove];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
[self sendAttachmentData:dataSource
|
|
|
|
|
contentType:contentType
|
|
|
|
|
sourceFilename:nil
|
|
|
|
|
inMessage:message
|
|
|
|
|
success:successWithDeleteHandler
|
|
|
|
|
failure:failureWithDeleteHandler];
|
|
|
|
|
[self enqueueOutgoingAttachment:dataSource
|
|
|
|
|
contentType:contentType
|
|
|
|
|
sourceFilename:nil
|
|
|
|
|
inMessage:message
|
|
|
|
|
success:successWithDeleteHandler
|
|
|
|
|
failure:failureWithDeleteHandler];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)sendAttachmentData:(DataSource *)dataSource
|
|
|
|
|
contentType:(NSString *)contentType
|
|
|
|
|
sourceFilename:(nullable NSString *)sourceFilename
|
|
|
|
|
inMessage:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(void (^)(NSError *error))failureHandler
|
|
|
|
|
- (void)enqueueOutgoingAttachment:(DataSource *)dataSource
|
|
|
|
|
contentType:(NSString *)contentType
|
|
|
|
|
sourceFilename:(nullable NSString *)sourceFilename
|
|
|
|
|
inMessage:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(void (^)(NSError *error))failureHandler
|
|
|
|
|
{
|
|
|
|
|
OWSAssert(dataSource);
|
|
|
|
|
|
|
|
|
@ -573,9 +568,8 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
if (sourceFilename) {
|
|
|
|
|
message.attachmentFilenameMap[attachmentStream.uniqueId] = sourceFilename;
|
|
|
|
|
}
|
|
|
|
|
[message save];
|
|
|
|
|
|
|
|
|
|
[self sendMessage:message success:successHandler failure:failureHandler];
|
|
|
|
|
[self enqueueOutgoingMessage:message success:successHandler failure:failureHandler];
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -605,9 +599,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
return [recipients copy];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)deliverMessage:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(RetryableFailureHandler)failureHandler
|
|
|
|
|
- (void)sendMessageToService:(TSOutgoingMessage *)message
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(RetryableFailureHandler)failureHandler
|
|
|
|
|
{
|
|
|
|
|
dispatch_async([OWSDispatch sendingQueue], ^{
|
|
|
|
|
TSThread *thread = message.thread;
|
|
|
|
@ -693,12 +687,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[self sendMessage:message
|
|
|
|
|
recipient:recipient
|
|
|
|
|
thread:thread
|
|
|
|
|
attempts:OWSMessageSenderRetryAttempts
|
|
|
|
|
success:successHandler
|
|
|
|
|
failure:failureHandler];
|
|
|
|
|
[self sendMessageToService:message
|
|
|
|
|
recipient:recipient
|
|
|
|
|
thread:thread
|
|
|
|
|
attempts:OWSMessageSenderRetryAttempts
|
|
|
|
|
success:successHandler
|
|
|
|
|
failure:failureHandler];
|
|
|
|
|
} else {
|
|
|
|
|
// Neither a group nor contact thread? This should never happen.
|
|
|
|
|
OWSFail(@"%@ Unknown message type: %@", self.logTag, NSStringFromClass([message class]));
|
|
|
|
@ -717,7 +711,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
{
|
|
|
|
|
TOCFutureSource *futureSource = [[TOCFutureSource alloc] init];
|
|
|
|
|
|
|
|
|
|
[self sendMessage:message
|
|
|
|
|
[self sendMessageToService:message
|
|
|
|
|
recipient:recipient
|
|
|
|
|
thread:thread
|
|
|
|
|
attempts:OWSMessageSenderRetryAttempts
|
|
|
|
@ -852,12 +846,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
}];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)sendMessage:(TSOutgoingMessage *)message
|
|
|
|
|
recipient:(SignalRecipient *)recipient
|
|
|
|
|
thread:(TSThread *)thread
|
|
|
|
|
attempts:(int)remainingAttempts
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(RetryableFailureHandler)failureHandler
|
|
|
|
|
- (void)sendMessageToService:(TSOutgoingMessage *)message
|
|
|
|
|
recipient:(SignalRecipient *)recipient
|
|
|
|
|
thread:(TSThread *)thread
|
|
|
|
|
attempts:(int)remainingAttempts
|
|
|
|
|
success:(void (^)(void))successHandler
|
|
|
|
|
failure:(RetryableFailureHandler)failureHandler
|
|
|
|
|
{
|
|
|
|
|
DDLogInfo(@"%@ attempting to send message: %@, timestamp: %llu, recipient: %@",
|
|
|
|
|
self.logTag,
|
|
|
|
@ -1048,7 +1042,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
long statuscode = response.statusCode;
|
|
|
|
|
NSData *responseData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
|
|
|
|
|
|
|
|
|
|
void (^retrySend)() = ^void() {
|
|
|
|
|
void (^retrySend)(void) = ^void() {
|
|
|
|
|
if (remainingAttempts <= 0) {
|
|
|
|
|
// Since we've already repeatedly failed to send to the messaging API,
|
|
|
|
|
// it's unlikely that repeating the whole process will succeed.
|
|
|
|
@ -1058,12 +1052,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
|
|
|
|
|
dispatch_async([OWSDispatch sendingQueue], ^{
|
|
|
|
|
DDLogDebug(@"%@ Retrying: %@", self.logTag, message.debugDescription);
|
|
|
|
|
[self sendMessage:message
|
|
|
|
|
recipient:recipient
|
|
|
|
|
thread:thread
|
|
|
|
|
attempts:remainingAttempts
|
|
|
|
|
success:successHandler
|
|
|
|
|
failure:failureHandler];
|
|
|
|
|
[self sendMessageToService:message
|
|
|
|
|
recipient:recipient
|
|
|
|
|
thread:thread
|
|
|
|
|
attempts:remainingAttempts
|
|
|
|
|
success:successHandler
|
|
|
|
|
failure:failureHandler];
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -1173,12 +1167,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
// TODO: I suspect we shouldn't optimistically set hasSyncedTranscript.
|
|
|
|
|
// We could set this in a success handler for [sendSyncTranscriptForMessage:].
|
|
|
|
|
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
|
|
|
|
// Update the message unless it has been deleted.
|
|
|
|
|
if ([TSOutgoingMessage fetchObjectWithUniqueID:message.uniqueId]) {
|
|
|
|
|
[message updateWithHasSyncedTranscript:YES transaction:transaction];
|
|
|
|
|
} else {
|
|
|
|
|
DDLogInfo(@"%@ not marking message as having synced transcript; message deleted.", self.logTag);
|
|
|
|
|
}
|
|
|
|
|
[message updateWithHasSyncedTranscript:YES transaction:transaction];
|
|
|
|
|
}];
|
|
|
|
|
[self sendSyncTranscriptForMessage:message];
|
|
|
|
|
}
|
|
|
|
@ -1259,7 +1248,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|
|
|
|
OWSOutgoingSentMessageTranscript *sentMessageTranscript =
|
|
|
|
|
[[OWSOutgoingSentMessageTranscript alloc] initWithOutgoingMessage:message];
|
|
|
|
|
|
|
|
|
|
[self sendMessage:sentMessageTranscript
|
|
|
|
|
[self sendMessageToService:sentMessageTranscript
|
|
|
|
|
recipient:[SignalRecipient selfRecipient]
|
|
|
|
|
thread:message.thread
|
|
|
|
|
attempts:OWSMessageSenderRetryAttempts
|
|
|
|
|