Rework the "update with..." methods to avoid re-saving deleted models.

This commit is contained in:
Matthew Chen 2017-11-15 06:39:10 -05:00
parent 69fa80b890
commit c6160a5a1e
24 changed files with 196 additions and 210 deletions

View File

@ -30,9 +30,9 @@ class SessionResetJob: NSObject {
self.storageManager.deleteAllSessions(forContact: self.recipientId)
DispatchQueue.main.async {
let endSessionMessage = EndSessionMessage(timestamp:NSDate.ows_millisecondTimeStamp(), in: self.thread)
let endSessionMessage = EndSessionMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: self.thread)
self.messageSender.send(endSessionMessage, success: {
self.messageSender.enqueue(endSessionMessage, success: {
Logger.info("\(self.TAG) successfully sent EndSession<essage.")
let message = TSInfoMessage(timestamp: NSDate.ows_millisecondTimeStamp(),
in: self.thread,

View File

@ -12,7 +12,7 @@ public extension MessageSender {
*/
public func sendPromise(message: TSOutgoingMessage) -> Promise<Void> {
let promise: Promise<Void> = Promise { fulfill, reject in
self.send(message, success: fulfill, failure: reject)
self.enqueue(message, success: fulfill, failure: reject)
}
// Ensure sends complete before they're GC'd.

View File

@ -43,8 +43,8 @@ import PromiseKit
identityManager: self.identityManager,
profileManager: self.profileManager)
let dataSource = DataSourceValue.dataSource(withSyncMessage:syncContactsMessage.buildPlainTextAttachmentData())
self.messageSender.sendTemporaryAttachmentData(dataSource,
let dataSource = DataSourceValue.dataSource(withSyncMessage: syncContactsMessage.buildPlainTextAttachmentData())
self.messageSender.enqueueOutgoingTemporaryAttachment(dataSource,
contentType: OWSMimeTypeApplicationOctetStream,
in: syncContactsMessage,
success: {

View File

@ -1465,7 +1465,7 @@ const NSUInteger kOWSProfileManager_MaxAvatarDiameter = 640;
return;
}
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent profile key message to thread: %@", self.logTag, thread);
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread];

View File

@ -1654,7 +1654,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
[UIAlertAction actionWithTitle:NSLocalizedString(@"SEND_AGAIN_BUTTON", @"")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully resent failed message.", self.logTag);
}
@ -3391,7 +3391,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
if (newGroupModel.groupImage) {
NSData *data = UIImagePNGRepresentation(newGroupModel.groupImage);
DataSource *_Nullable dataSource = [DataSourceValue dataSourceWithData:data fileExtension:@"png"];
[self.messageSender sendAttachmentData:dataSource
[self.messageSender enqueueOutgoingAttachment:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
inMessage:message
@ -3405,7 +3405,7 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
DDLogError(@"%@ Failed to send group avatar update with error: %@", self.logTag, error);
}];
} else {
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogDebug(@"%@ Successfully sent group update", self.logTag);
if (successCompletion) {

View File

@ -219,7 +219,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSyncGroupsRequestMessage *syncGroupsRequestMessage =
[[OWSSyncGroupsRequestMessage alloc] initWithThread:thread
groupId:[Randomness generateRandomBytes:16]];
[[Environment getCurrent].messageSender sendMessage:syncGroupsRequestMessage
[[Environment getCurrent].messageSender enqueueOutgoingMessage:syncGroupsRequestMessage
success:^{
DDLogWarn(@"%@ Successfully sent Request Group Info message.", self.logTag);
}
@ -1055,7 +1055,6 @@ NS_ASSUME_NONNULL_BEGIN
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
groupMetaMessage:TSGroupMessageNew];
// This will save the message.
[message updateWithCustomMessage:NSLocalizedString(@"GROUP_CREATED", nil)];
OWSMessageSender *messageSender = [Environment getCurrent].messageSender;
@ -1067,11 +1066,11 @@ NS_ASSUME_NONNULL_BEGIN
});
});
};
[messageSender sendMessage:message
success:completion
failure:^(NSError *error) {
completion();
}];
[messageSender enqueueOutgoingMessage:message
success:completion
failure:^(NSError *error) {
completion();
}];
}
+ (void)injectFakeIncomingMessages:(int)counter thread:(TSThread *)thread

View File

@ -437,7 +437,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(message);
OWSMessageSender *messageSender = [Environment getCurrent].messageSender;
[messageSender sendMessage:message
[messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent message.", self.logTag);
}

View File

@ -679,7 +679,7 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
groupMetaMessage:TSGroupMessageQuit];
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
[self dismissViewControllerAnimated:YES
completion:^{

View File

@ -493,7 +493,6 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
inThread:thread
groupMetaMessage:TSGroupMessageNew];
// This will save the message.
[message updateWithCustomMessage:NSLocalizedString(@"GROUP_CREATED", nil)];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@ -501,14 +500,16 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
NSData *data = UIImagePNGRepresentation(model.groupImage);
DataSource *_Nullable dataSource =
[DataSourceValue dataSourceWithData:data fileExtension:@"png"];
[self.messageSender sendAttachmentData:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
inMessage:message
success:successHandler
failure:failureHandler];
[self.messageSender enqueueOutgoingAttachment:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
inMessage:message
success:successHandler
failure:failureHandler];
} else {
[self.messageSender sendMessage:message success:successHandler failure:failureHandler];
[self.messageSender enqueueOutgoingMessage:message
success:successHandler
failure:failureHandler];
}
});
}];

View File

@ -885,7 +885,7 @@ NS_ASSUME_NONNULL_BEGIN
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:gThread
groupMetaMessage:TSGroupMessageQuit];
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully left group.", self.logTag);
}

View File

@ -115,7 +115,7 @@ NSString *const kTSStorageManagerOWSContactsSyncingLastMessageKey =
DataSource *dataSource =
[DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]];
[self.messageSender sendTemporaryAttachmentData:dataSource
[self.messageSender enqueueOutgoingTemporaryAttachment:dataSource
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncContactsMessage
success:^{

View File

@ -86,7 +86,7 @@ NS_ASSUME_NONNULL_BEGIN
attachmentIds:[NSMutableArray new]
expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)];
[messageSender sendMessage:message success:successHandler failure:failureHandler];
[messageSender enqueueOutgoingMessage:message success:successHandler failure:failureHandler];
return message;
}
@ -117,7 +117,7 @@ NS_ASSUME_NONNULL_BEGIN
inThread:thread
isVoiceMessage:[attachment isVoiceMessage]
expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)];
[messageSender sendAttachmentData:attachment.dataSource
[messageSender enqueueOutgoingAttachment:attachment.dataSource
contentType:attachment.mimeType
sourceFilename:attachment.filenameOrDefault
inMessage:message

View File

@ -157,18 +157,19 @@ NS_ASSUME_NONNULL_BEGIN
@property (atomic, readonly, nullable) NSDate *mutedUntilDate;
// This model may be updated from many threads. We don't want to save
// our local copy (this instance) since it may be out of date. Instead, we
// our local copy (this instance) since it may be out of date. We also
// want to avoid re-saving a model that has been deleted. Therefore, we
// use these "updateWith..." methods to:
//
// a) Update a property of this instance.
// b) Load an up-to-date instance of this model from from the data store.
// c) Update and save that fresh instance.
// d) If this instance hasn't yet been saved, save this local instance.
// b) If a copy of this model exists in the database, load an up-to-date copy,
// and update and save that copy.
// b) If a copy of this model _DOES NOT_ exist in the database, do _NOT_ save
// this local instance.
//
// After "updateWith...":
//
// a) An updated copy of this instance will always have been saved in the
// data store.
// a) An copy of this model in the database will have been updated.
// b) The local property on this instance will always have been updated.
// c) Other properties on this instance may be out of date.
//

View File

@ -384,8 +384,8 @@ NS_ASSUME_NONNULL_BEGIN
// This method does the work for the "updateWith..." methods. Please see
// the header for a discussion of those methods.
- (void)applyChangeToSelfAndLatestThread:(YapDatabaseReadWriteTransaction *)transaction
changeBlock:(void (^)(TSThread *))changeBlock
- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction
changeBlock:(void (^)(TSThread *))changeBlock
{
OWSAssert(transaction);
@ -396,19 +396,16 @@ NS_ASSUME_NONNULL_BEGIN
if (latestInstance) {
changeBlock(latestInstance);
[latestInstance saveWithTransaction:transaction];
} else {
// This message has not yet been saved.
[self saveWithTransaction:transaction];
}
}
- (void)updateWithMutedUntilDate:(NSDate *)mutedUntilDate
{
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self applyChangeToSelfAndLatestThread:transaction
changeBlock:^(TSThread *thread) {
[thread setMutedUntilDate:mutedUntilDate];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSThread *thread) {
[thread setMutedUntilDate:mutedUntilDate];
}];
}];
}

View File

@ -109,6 +109,7 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
[outgoingMessage saveWithTransaction:transaction];
[outgoingMessage updateWithWasSentFromLinkedDeviceWithTransaction:transaction];
[OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage
contactsManager:self.contactsManager];
@ -138,6 +139,7 @@ NS_ASSUME_NONNULL_BEGIN
expiresInSeconds:transcript.expirationDuration
expireStartedAt:transcript.expirationStartedAt];
// Since textMessage is a new message, updateWithWasSentAndDelivered will save it.
[textMessage saveWithTransaction:transaction];
[textMessage updateWithWasSentFromLinkedDeviceWithTransaction:transaction];
}
}

View File

@ -148,19 +148,20 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
- (OWSSignalServiceProtosAttachmentPointer *)buildAttachmentProtoForAttachmentId:(NSString *)attachmentId
filename:(nullable NSString *)filename;
// TSOutgoingMessage are updated from many threads. We don't want to save
// our local copy (this instance) since it may be out of date. Instead, we
// This model may be updated from many threads. We don't want to save
// our local copy (this instance) since it may be out of date. We also
// want to avoid re-saving a model that has been deleted. Therefore, we
// use these "updateWith..." methods to:
//
// a) Update a property of this instance.
// b) Load an up-to-date instance of this model from from the data store.
// c) Update and save that fresh instance.
// d) If this message hasn't yet been saved, save this local instance.
// b) If a copy of this model exists in the database, load an up-to-date copy,
// and update and save that copy.
// b) If a copy of this model _DOES NOT_ exist in the database, do _NOT_ save
// this local instance.
//
// After "updateWith...":
//
// a) An updated copy of this message will always have been saved in the
// data store.
// a) An copy of this model in the database will have been updated.
// b) The local property on this instance will always have been updated.
// c) Other properties on this instance may be out of date.
//

View File

@ -242,8 +242,8 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
// This method does the work for the "updateWith..." methods. Please see
// the header for a discussion of those methods.
- (void)applyChangeToSelfAndLatestOutgoingMessage:(YapDatabaseReadWriteTransaction *)transaction
changeBlock:(void (^)(TSOutgoingMessage *))changeBlock
- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction
changeBlock:(void (^)(TSOutgoingMessage *))changeBlock
{
OWSAssert(transaction);
@ -254,9 +254,6 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
if (latestMessage) {
changeBlock(latestMessage);
[latestMessage saveWithTransaction:transaction];
} else {
// This message has not yet been saved.
[self saveWithTransaction:transaction];
}
}
@ -265,11 +262,11 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
OWSAssert(error);
[self.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setMessageState:TSOutgoingMessageStateUnsent];
[message setMostRecentFailureText:error.localizedDescription];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setMessageState:TSOutgoingMessageStateUnsent];
[message setMostRecentFailureText:error.localizedDescription];
}];
}];
}
@ -285,19 +282,19 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
{
OWSAssert(transaction);
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setMessageState:messageState];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setMessageState:messageState];
}];
}
- (void)updateWithHasSyncedTranscript:(BOOL)hasSyncedTranscript
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setHasSyncedTranscript:hasSyncedTranscript];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setHasSyncedTranscript:hasSyncedTranscript];
}];
}
- (void)updateWithCustomMessage:(NSString *)customMessage transaction:(YapDatabaseReadWriteTransaction *)transaction
@ -305,10 +302,10 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
OWSAssert(customMessage);
OWSAssert(transaction);
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setCustomMessage:customMessage];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setCustomMessage:customMessage];
}];
}
- (void)updateWithCustomMessage:(NSString *)customMessage
@ -325,32 +322,31 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
OWSAssert(recipientId.length > 0);
OWSAssert(transaction);
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
if (deliveryTimestamp) {
NSMutableDictionary<NSString *, NSNumber *> *recipientDeliveryMap
= (message.recipientDeliveryMap
? [message.recipientDeliveryMap mutableCopy]
: [NSMutableDictionary new]);
recipientDeliveryMap[recipientId] = deliveryTimestamp;
message.recipientDeliveryMap = [recipientDeliveryMap copy];
}
if (deliveryTimestamp) {
NSMutableDictionary<NSString *, NSNumber *> *recipientDeliveryMap
= (message.recipientDeliveryMap ? [message.recipientDeliveryMap mutableCopy]
: [NSMutableDictionary new]);
recipientDeliveryMap[recipientId] = deliveryTimestamp;
message.recipientDeliveryMap = [recipientDeliveryMap copy];
}
[message setWasDelivered:YES];
}];
[message setWasDelivered:YES];
}];
}
- (void)updateWithWasSentFromLinkedDeviceWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(transaction);
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setMessageState:TSOutgoingMessageStateSentToService];
[message setWasDelivered:YES];
[message setIsFromLinkedDevice:YES];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setMessageState:TSOutgoingMessageStateSentToService];
[message setWasDelivered:YES];
[message setIsFromLinkedDevice:YES];
}];
}
- (void)updateWithSingleGroupRecipient:(NSString *)singleGroupRecipient
@ -359,10 +355,10 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
OWSAssert(transaction);
OWSAssert(singleGroupRecipient.length > 0);
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setSingleGroupRecipient:singleGroupRecipient];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message setSingleGroupRecipient:singleGroupRecipient];
}];
}
#pragma mark - Sent Recipients
@ -414,10 +410,10 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
- (void)updateWithSentRecipient:(NSString *)contactId transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(transaction);
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message addSentRecipient:contactId];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
[message addSentRecipient:contactId];
}];
}
- (void)updateWithReadRecipientId:(NSString *)recipientId
@ -427,14 +423,14 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
OWSAssert(recipientId.length > 0);
OWSAssert(transaction);
[self applyChangeToSelfAndLatestOutgoingMessage:transaction
changeBlock:^(TSOutgoingMessage *message) {
NSMutableDictionary<NSString *, NSNumber *> *recipientReadMap
= (message.recipientReadMap ? [message.recipientReadMap mutableCopy]
: [NSMutableDictionary new]);
recipientReadMap[recipientId] = @(readTimestamp);
message.recipientReadMap = [recipientReadMap copy];
}];
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) {
NSMutableDictionary<NSString *, NSNumber *> *recipientReadMap
= (message.recipientReadMap ? [message.recipientReadMap mutableCopy]
: [NSMutableDictionary new]);
recipientReadMap[recipientId] = @(readTimestamp);
message.recipientReadMap = [recipientReadMap copy];
}];
}
- (nullable NSNumber *)firstRecipientReadTimestamp

View File

@ -258,7 +258,7 @@ NSString *const kOWSBlockingManager_SyncedBlockedPhoneNumbersKey = @"kOWSBlockin
OWSBlockedPhoneNumbersMessage *message =
[[OWSBlockedPhoneNumbersMessage alloc] initWithPhoneNumbers:blockedPhoneNumbers];
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent blocked phone numbers sync message", self.logTag);

View File

@ -517,10 +517,10 @@ NSString *const kNSNotificationName_IdentityStateDidChange = @"kNSNotificationNa
// subsequently
OWSOutgoingNullMessage *nullMessage = [[OWSOutgoingNullMessage alloc] initWithContactThread:contactThread
verificationStateSyncMessage:message];
[self.messageSender sendMessage:nullMessage
[self.messageSender enqueueOutgoingMessage:nullMessage
success:^{
DDLogInfo(@"%@ Successfully sent verification state NullMessage", self.logTag);
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent verification state sync message", self.logTag);

View File

@ -366,7 +366,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSyncGroupsRequestMessage *syncGroupsRequestMessage =
[[OWSSyncGroupsRequestMessage alloc] initWithThread:thread groupId:groupId];
[self.messageSender sendMessage:syncGroupsRequestMessage
[self.messageSender enqueueOutgoingMessage:syncGroupsRequestMessage
success:^{
DDLogWarn(@"%@ Successfully sent Request Group Info message.", self.logTag);
}
@ -609,7 +609,7 @@ NS_ASSUME_NONNULL_BEGIN
profileManager:self.profileManager];
DataSource *dataSource =
[DataSourceValue dataSourceWithSyncMessage:[syncContactsMessage buildPlainTextAttachmentData]];
[self.messageSender sendTemporaryAttachmentData:dataSource
[self.messageSender enqueueOutgoingTemporaryAttachment:dataSource
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncContactsMessage
success:^{
@ -622,7 +622,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSSyncGroupsMessage *syncGroupsMessage = [[OWSSyncGroupsMessage alloc] init];
DataSource *dataSource = [DataSourceValue
dataSourceWithSyncMessage:[syncGroupsMessage buildPlainTextAttachmentDataWithTransaction:transaction]];
[self.messageSender sendTemporaryAttachmentData:dataSource
[self.messageSender enqueueOutgoingTemporaryAttachment:dataSource
contentType:OWSMimeTypeApplicationOctetStream
inMessage:syncGroupsMessage
success:^{
@ -639,7 +639,7 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSReadReceiptManager sharedManager] areReadReceiptsEnabledWithTransaction:transaction];
OWSSyncConfigurationMessage *syncConfigurationMessage =
[[OWSSyncConfigurationMessage alloc] initWithReadReceiptsEnabled:areReadReceiptsEnabled];
[self.messageSender sendMessage:syncConfigurationMessage
[self.messageSender enqueueOutgoingMessage:syncConfigurationMessage
success:^{
DDLogInfo(@"%@ Successfully sent Configuration response syncMessage.", self.logTag);
}
@ -774,7 +774,7 @@ NS_ASSUME_NONNULL_BEGIN
if (gThread.groupModel.groupImage) {
NSData *data = UIImagePNGRepresentation(gThread.groupModel.groupImage);
DataSource *_Nullable dataSource = [DataSourceValue dataSourceWithData:data fileExtension:@"png"];
[self.messageSender sendAttachmentData:dataSource
[self.messageSender enqueueOutgoingAttachment:dataSource
contentType:OWSMimeTypeImagePng
sourceFilename:nil
inMessage:message
@ -785,7 +785,7 @@ NS_ASSUME_NONNULL_BEGIN
DDLogError(@"%@ Failed to send group avatar update with error: %@", self.logTag, error);
}];
} else {
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogDebug(@"%@ Successfully sent group update", self.logTag);
}

View File

@ -63,33 +63,33 @@ NS_SWIFT_NAME(MessageSender)
/**
* Send and resend text messages or resend messages with existing attachments.
* If you haven't yet created the attachment, see the `sendAttachmentData:` variants.
* If you haven't yet created the attachment, see the ` enqueueOutgoingAttachment:` variants.
*/
// TODO: make transaction nonnull and remove `sendMessage:success:failure`
- (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;
/**
* Takes care of allocating and uploading the attachment, then sends the message.
* Only necessary to call once. If sending fails, retry with `sendMessage:`.
*/
- (void)sendAttachmentData:(DataSource *)dataSource
contentType:(NSString *)contentType
sourceFilename:(nullable NSString *)sourceFilename
inMessage:(TSOutgoingMessage *)outgoingMessage
success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler;
- (void)enqueueOutgoingAttachment:(DataSource *)dataSource
contentType:(NSString *)contentType
sourceFilename:(nullable NSString *)sourceFilename
inMessage:(TSOutgoingMessage *)outgoingMessage
success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler;
/**
* Same as `sendAttachmentData:`, but deletes the local copy of the attachment after sending.
* Same as ` enqueueOutgoingAttachment:`, but deletes the local copy of the attachment after sending.
* Used for sending sync request data, not for user visible attachments.
*/
- (void)sendTemporaryAttachmentData:(DataSource *)dataSource
contentType:(NSString *)contentType
inMessage:(TSOutgoingMessage *)outgoingMessage
success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler;
- (void)enqueueOutgoingTemporaryAttachment:(DataSource *)dataSource
contentType:(NSString *)contentType
inMessage:(TSOutgoingMessage *)outgoingMessage
success:(void (^)(void))successHandler
failure:(void (^)(NSError *error))failureHandler;
/**
* Set local configuration to match that of the of `outgoingMessage`'s sender

View File

@ -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

View File

@ -49,7 +49,7 @@ NS_ASSUME_NONNULL_BEGIN
[[OWSDisappearingMessagesConfigurationMessage alloc] initWithConfiguration:self.configuration
thread:self.thread];
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogDebug(
@"%@ Successfully notified %@ of new disappearing messages configuration", self.logTag, self.thread);

View File

@ -229,7 +229,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
OWSReadReceiptsForLinkedDevicesMessage *message =
[[OWSReadReceiptsForLinkedDevicesMessage alloc] initWithReadReceipts:readReceiptsForLinkedDevices];
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent %zd read receipt to linked devices.",
self.logTag,
@ -253,7 +253,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
[[OWSReadReceiptsForSenderMessage alloc] initWithThread:thread
messageTimestamps:timestamps.allObjects];
[self.messageSender sendMessage:message
[self.messageSender enqueueOutgoingMessage:message
success:^{
DDLogInfo(@"%@ Successfully sent %zd read receipts to sender.", self.logTag, timestamps.count);
}
@ -590,7 +590,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
OWSSyncConfigurationMessage *syncConfigurationMessage =
[[OWSSyncConfigurationMessage alloc] initWithReadReceiptsEnabled:value];
[self.messageSender sendMessage:syncConfigurationMessage
[self.messageSender enqueueOutgoingMessage:syncConfigurationMessage
success:^{
DDLogInfo(@"%@ Successfully sent Configuration syncMessage.", self.logTag);
}