From dfb2a034af81834fa2fea41beeb03e8e92868550 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Mon, 16 Apr 2018 18:38:29 -0400 Subject: [PATCH] Use explicit transactions. - Start expiration within scope of existing transaction when we're already in a transaction // FREEBIE --- .../ViewControllers/DebugUI/DebugUIMessages.m | 8 +- .../OWSDisappearingMessagesConfiguration.h | 5 +- .../OWSDisappearingMessagesConfiguration.m | 4 +- SignalServiceKit/src/Contacts/TSThread.m | 2 +- .../src/Devices/OWSRecordTranscriptJob.m | 18 +- .../Messages/Interactions/TSErrorMessage.m | 3 +- .../Messages/Interactions/TSIncomingMessage.m | 9 +- .../src/Messages/Interactions/TSInfoMessage.m | 3 +- .../src/Messages/OWSDisappearingMessagesJob.h | 16 +- .../src/Messages/OWSDisappearingMessagesJob.m | 180 +++++++----------- .../src/Messages/OWSMessageManager.m | 7 +- .../src/Messages/OWSMessageSender.h | 8 - .../src/Messages/OWSMessageSender.m | 11 +- .../src/Messages/OWSReadReceiptManager.m | 21 +- .../src/Messages/OWSReadTracking.h | 7 +- SignalServiceKit/src/Messages/TSCall.m | 3 +- 16 files changed, 142 insertions(+), 163 deletions(-) diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m index e38bafbf9..b0452a11f 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMessages.m @@ -3278,7 +3278,7 @@ NS_ASSUME_NONNULL_BEGIN attachmentIds:@[] expiresInSeconds:0 quotedMessage:nil]; - [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; + [message markAsReadWithTransaction:transaction sendReadReceipt:NO]; break; } case 1: { @@ -3316,7 +3316,7 @@ NS_ASSUME_NONNULL_BEGIN ] expiresInSeconds:0 quotedMessage:nil]; - [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; + [message markAsReadWithTransaction:transaction sendReadReceipt:NO]; break; } case 3: { @@ -3767,7 +3767,7 @@ NS_ASSUME_NONNULL_BEGIN attachmentIds:[NSMutableArray new] expiresInSeconds:0 quotedMessage:nil]; - [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; + [message markAsReadWithTransaction:transaction sendReadReceipt:NO]; } { TSOutgoingMessage *message = @@ -4105,7 +4105,7 @@ NS_ASSUME_NONNULL_BEGIN attachmentIds:attachmentIds expiresInSeconds:0 quotedMessage:quotedMessage]; - [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; + [message markAsReadWithTransaction:transaction sendReadReceipt:NO]; return message; } diff --git a/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.h b/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.h index dc3bdbf35..efd28287f 100644 --- a/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.h +++ b/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.h @@ -8,6 +8,8 @@ NS_ASSUME_NONNULL_BEGIN #define OWSDisappearingMessagesConfigurationDefaultExpirationDuration kDayInterval +@class YapDatabaseReadTransaction; + @interface OWSDisappearingMessagesConfiguration : TSYapDatabaseObject - (instancetype)initDefaultWithThreadId:(NSString *)threadId; @@ -21,7 +23,8 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) BOOL dictionaryValueDidChange; @property (readonly, getter=isNewRecord) BOOL newRecord; -+ (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId; ++ (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId + transaction:(YapDatabaseReadTransaction *)transaction; + (NSArray *)validDurationsSeconds; diff --git a/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.m b/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.m index 0ca190426..4fa0f343e 100644 --- a/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.m +++ b/SignalServiceKit/src/Contacts/OWSDisappearingMessagesConfiguration.m @@ -51,8 +51,10 @@ NS_ASSUME_NONNULL_BEGIN } + (instancetype)fetchOrCreateDefaultWithThreadId:(NSString *)threadId + transaction:(YapDatabaseReadTransaction *)transaction { - OWSDisappearingMessagesConfiguration *savedConfiguration = [self fetchObjectWithUniqueID:threadId]; + OWSDisappearingMessagesConfiguration *savedConfiguration = + [self fetchObjectWithUniqueID:threadId transaction:transaction]; if (savedConfiguration) { return savedConfiguration; } else { diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index b4798cdfa..78bfffeb9 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -230,7 +230,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction { for (id message in [self unseenMessagesWithTransaction:transaction]) { - [message markAsReadWithTransaction:transaction sendReadReceipt:YES updateExpiration:YES]; + [message markAsReadWithTransaction:transaction sendReadReceipt:YES]; } // Just to be defensive, we'll also check for unread messages. diff --git a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m index 72a2177dc..999b4d508 100644 --- a/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m +++ b/SignalServiceKit/src/Devices/OWSRecordTranscriptJob.m @@ -134,9 +134,13 @@ NS_ASSUME_NONNULL_BEGIN } if (transcript.isExpirationTimerUpdate) { - [OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage - contactsManager:self.contactsManager]; + [[OWSDisappearingMessagesJob sharedJob] becomeConsistentWithConfigurationForMessage:outgoingMessage + contactsManager:self.contactsManager + transaction:transaction]; // early return to avoid saving an empty incoming message. + OWSAssert(transcript.body.length == 0); + OWSAssert(outgoingMessage.attachmentIds.count == 0); + return; } @@ -147,10 +151,12 @@ NS_ASSUME_NONNULL_BEGIN [outgoingMessage saveWithTransaction:transaction]; [outgoingMessage updateWithWasSentFromLinkedDeviceWithTransaction:transaction]; - [OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage - contactsManager:self.contactsManager]; - [OWSDisappearingMessagesJob setExpirationForMessage:outgoingMessage - expirationStartedAt:transcript.expirationStartedAt]; + [[OWSDisappearingMessagesJob sharedJob] becomeConsistentWithConfigurationForMessage:outgoingMessage + contactsManager:self.contactsManager + transaction:transaction]; + [[OWSDisappearingMessagesJob sharedJob] setExpirationForMessage:outgoingMessage + expirationStartedAt:transcript.expirationStartedAt + transaction:transaction]; [self.readReceiptManager applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:outgoingMessage transaction:transaction]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m b/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m index 497aca868..97693e429 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSErrorMessage.m @@ -186,7 +186,6 @@ NSUInteger TSErrorMessageSchemaVersion = 1; - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction sendReadReceipt:(BOOL)sendReadReceipt - updateExpiration:(BOOL)updateExpiration { OWSAssert(transaction); @@ -200,7 +199,7 @@ NSUInteger TSErrorMessageSchemaVersion = 1; [self saveWithTransaction:transaction]; [self touchThreadWithTransaction:transaction]; - // Ignore sendReadReceipt and updateExpiration; they don't apply to error messages. + // Ignore sendReadReceipt - it doesn't apply to error messages. } @end diff --git a/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m b/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m index 87209f0a1..e106cb28d 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSIncomingMessage.m @@ -136,7 +136,6 @@ NS_ASSUME_NONNULL_BEGIN - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction sendReadReceipt:(BOOL)sendReadReceipt - updateExpiration:(BOOL)updateExpiration { OWSAssert(transaction); @@ -149,10 +148,10 @@ NS_ASSUME_NONNULL_BEGIN _read = YES; [self saveWithTransaction:transaction]; [self touchThreadWithTransaction:transaction]; - - if (updateExpiration) { - [OWSDisappearingMessagesJob setExpirationForMessage:self]; - } + + [[OWSDisappearingMessagesJob sharedJob] startExpirationForMessage:self + transaction:transaction]; + if (sendReadReceipt) { [OWSReadReceiptManager.sharedManager messageWasReadLocally:self]; diff --git a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m index 4c53c8cc5..11bb4075b 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSInfoMessage.m @@ -131,7 +131,6 @@ NSUInteger TSInfoMessageSchemaVersion = 1; - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction sendReadReceipt:(BOOL)sendReadReceipt - updateExpiration:(BOOL)updateExpiration { OWSAssert(transaction); @@ -145,7 +144,7 @@ NSUInteger TSInfoMessageSchemaVersion = 1; [self saveWithTransaction:transaction]; [self touchThreadWithTransaction:transaction]; - // Ignore sendReadReceipt and updateExpiration; they don't apply to info messages. + // Ignore sendReadReceipt, it doesn't apply to info messages. } @end diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.h b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.h index 9b6820a89..5f80529c3 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.h +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.h @@ -7,6 +7,7 @@ NS_ASSUME_NONNULL_BEGIN @class OWSPrimaryStorage; @class TSMessage; @class TSThread; +@class YapDatabaseReadWriteTransaction; @protocol ContactsManagerProtocol; @@ -16,9 +17,13 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)init NS_UNAVAILABLE; -+ (void)setExpirationsForThread:(TSThread *)thread; -+ (void)setExpirationForMessage:(TSMessage *)message; -+ (void)setExpirationForMessage:(TSMessage *)message expirationStartedAt:(uint64_t)expirationStartedAt; +//+ (void)setExpirationsForThread:(TSThread *)thread; +- (void)startExpirationForMessage:(TSMessage *)message + transaction:(YapDatabaseReadWriteTransaction *_Nonnull)transaction; + +- (void)setExpirationForMessage:(TSMessage *)message + expirationStartedAt:(uint64_t)expirationStartedAt + transaction:(YapDatabaseReadWriteTransaction *_Nonnull)transaction; /** * Synchronize our disappearing messages settings with that of the given message. Useful so we can @@ -31,8 +36,9 @@ NS_ASSUME_NONNULL_BEGIN * @param contactsManager * Provides the contact name responsible for any configuration changes in an info message. */ -+ (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message - contactsManager:(id)contactsManager; +- (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message + contactsManager:(id)contactsManager + transaction:(YapDatabaseReadWriteTransaction *)transaction; // Clean up any messages that expired since last launch immediately // and continue cleaning in the background. diff --git a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m index 81c53c212..84521a033 100644 --- a/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m +++ b/SignalServiceKit/src/Messages/OWSDisappearingMessagesJob.m @@ -166,42 +166,23 @@ void AssertIsOnDisappearingMessagesQueue() return deletedCount; } -+ (void)setExpirationForMessage:(TSMessage *)message -{ - dispatch_async(self.serialQueue, ^{ - [[self sharedJob] setExpirationForMessage:message]; - }); -} - -- (void)setExpirationForMessage:(TSMessage *)message +- (void)startExpirationForMessage:(TSMessage *)message + transaction:(YapDatabaseReadWriteTransaction *_Nonnull)transaction { if (!message.isExpiringMessage) { return; } OWSDisappearingMessagesConfiguration *disappearingConfig = - [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:message.uniqueThreadId]; + [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:message.uniqueThreadId transaction:transaction]; if (!disappearingConfig.isEnabled) { return; } - [self setExpirationForMessage:message expirationStartedAt:[NSDate ows_millisecondTimeStamp]]; -} - -+ (void)setExpirationForMessage:(TSMessage *)message expirationStartedAt:(uint64_t)expirationStartedAt -{ - dispatch_async(self.serialQueue, ^{ - [[self sharedJob] setExpirationForMessage:message expirationStartedAt:expirationStartedAt]; - }); -} - -// This method should only be called on the serialQueue. -- (void)setExpirationForMessage:(TSMessage *)message expirationStartedAt:(uint64_t)expirationStartedAt -{ - [self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self setExpirationForMessage:message expirationStartedAt:expirationStartedAt transaction:transaction]; - }]; + [self setExpirationForMessage:message + expirationStartedAt:[NSDate ows_millisecondTimeStamp] + transaction:transaction]; } - (void)setExpirationForMessage:(TSMessage *)message @@ -222,106 +203,93 @@ void AssertIsOnDisappearingMessagesQueue() [message updateWithExpireStartedAt:expirationStartedAt transaction:transaction]; } - // Necessary that the async expiration run happens *after* the message is saved with expiration configuration. - [self scheduleRunByDate:[NSDate ows_dateWithMillisecondsSince1970:message.expiresAt]]; -} - -+ (void)setExpirationsForThread:(TSThread *)thread -{ - dispatch_async(self.serialQueue, ^{ - [[self sharedJob] setExpirationsForThread:thread]; - }); + [transaction addCompletionQueue:nil + completionBlock:^{ + // Necessary that the async expiration run happens *after* the message is saved with it's new + // expiration configuration. + [self scheduleRunByDate:[NSDate ows_dateWithMillisecondsSince1970:message.expiresAt]]; + }]; } -// This method should only be called on the serialQueue. -- (void)setExpirationsForThread:(TSThread *)thread +- (void)setExpirationsForThread:(TSThread *)thread transaction:(YapDatabaseReadWriteTransaction *)transaction { OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; uint64_t now = [NSDate ows_millisecondTimeStamp]; - [self.databaseConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) { - [self.disappearingMessagesFinder - enumerateUnstartedExpiringMessagesInThread:thread - block:^(TSMessage *_Nonnull message) { - DDLogWarn( - @"%@ Starting expiring message which should have already " - @"been started.", - self.logTag); - // specify "now" in case D.M. have since been disabled, but we have - // existing unstarted expiring messages that still need to expire. - [self setExpirationForMessage:message - expirationStartedAt:now - transaction:transaction]; - } - transaction:transaction]; - }]; + [self.disappearingMessagesFinder + enumerateUnstartedExpiringMessagesInThread:thread + block:^(TSMessage *_Nonnull message) { + DDLogWarn(@"%@ Starting expiring message which should have already " + @"been started.", + self.logTag); + // specify "now" in case D.M. have since been disabled, but we have + // existing unstarted expiring messages that still need to expire. + [self setExpirationForMessage:message + expirationStartedAt:now + transaction:transaction]; + } + transaction:transaction]; backgroundTask = nil; } -+ (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message - contactsManager:(id)contactsManager -{ - [[self sharedJob] becomeConsistentWithConfigurationForMessage:message contactsManager:contactsManager]; -} - - (void)becomeConsistentWithConfigurationForMessage:(TSMessage *)message contactsManager:(id)contactsManager + transaction:(YapDatabaseReadWriteTransaction *)transaction { OWSAssert(message); OWSAssert(contactsManager); - + __block OWSBackgroundTask *_Nullable backgroundTask = [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; - - dispatch_async(OWSDisappearingMessagesJob.serialQueue, ^{ - // Become eventually consistent in the case that the remote changed their settings at the same time. - // Also in case remote doesn't support expiring messages - OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration = - [OWSDisappearingMessagesConfiguration fetchOrCreateDefaultWithThreadId:message.uniqueThreadId]; - - BOOL changed = NO; - if (message.expiresInSeconds == 0) { - if (disappearingMessagesConfiguration.isEnabled) { - changed = YES; - DDLogWarn(@"%@ Received remote message which had no expiration set, disabling our expiration to become " - @"consistent.", - self.logTag); - disappearingMessagesConfiguration.enabled = NO; - [disappearingMessagesConfiguration save]; - } - } else if (message.expiresInSeconds != disappearingMessagesConfiguration.durationSeconds) { + + // Become eventually consistent in the case that the remote changed their settings at the same time. + // Also in case remote doesn't support expiring messages + OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration = + [OWSDisappearingMessagesConfiguration fetchOrCreateDefaultWithThreadId:message.uniqueThreadId + transaction:transaction]; + + BOOL changed = NO; + if (message.expiresInSeconds == 0) { + if (disappearingMessagesConfiguration.isEnabled) { changed = YES; - DDLogInfo(@"%@ Received remote message with different expiration set, updating our expiration to become " + DDLogWarn(@"%@ Received remote message which had no expiration set, disabling our expiration to become " @"consistent.", - self.logTag); - disappearingMessagesConfiguration.enabled = YES; - disappearingMessagesConfiguration.durationSeconds = message.expiresInSeconds; - [disappearingMessagesConfiguration save]; - } - - if (!changed) { - return; - } - - if ([message isKindOfClass:[TSIncomingMessage class]]) { - TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message; - NSString *contactName = [contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId]; - - // We want the info message to appear _before_ the message. - [[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1 - thread:message.thread - configuration:disappearingMessagesConfiguration - createdByRemoteName:contactName] save]; - } else { - // We want the info message to appear _before_ the message. - [[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1 - thread:message.thread - configuration:disappearingMessagesConfiguration] - save]; + self.logTag); + disappearingMessagesConfiguration.enabled = NO; + [disappearingMessagesConfiguration saveWithTransaction:transaction]; } - - backgroundTask = nil; - }); + } else if (message.expiresInSeconds != disappearingMessagesConfiguration.durationSeconds) { + changed = YES; + DDLogInfo(@"%@ Received remote message with different expiration set, updating our expiration to become " + @"consistent.", + self.logTag); + disappearingMessagesConfiguration.enabled = YES; + disappearingMessagesConfiguration.durationSeconds = message.expiresInSeconds; + [disappearingMessagesConfiguration saveWithTransaction:transaction]; + } + + if (!changed) { + return; + } + + if ([message isKindOfClass:[TSIncomingMessage class]]) { + TSIncomingMessage *incomingMessage = (TSIncomingMessage *)message; + NSString *contactName = [contactsManager displayNameForPhoneIdentifier:incomingMessage.messageAuthorId]; + + // We want the info message to appear _before_ the message. + [[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1 + thread:message.thread + configuration:disappearingMessagesConfiguration + createdByRemoteName:contactName] saveWithTransaction:transaction]; + } else { + // We want the info message to appear _before_ the message. + [[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:message.timestamp - 1 + thread:message.thread + configuration:disappearingMessagesConfiguration] + saveWithTransaction:transaction]; + } + + backgroundTask = nil; } - (void)startIfNecessary diff --git a/SignalServiceKit/src/Messages/OWSMessageManager.m b/SignalServiceKit/src/Messages/OWSMessageManager.m index 1c64c563b..1096823b6 100644 --- a/SignalServiceKit/src/Messages/OWSMessageManager.m +++ b/SignalServiceKit/src/Messages/OWSMessageManager.m @@ -1092,7 +1092,7 @@ NS_ASSUME_NONNULL_BEGIN BOOL shouldMarkMessageAsRead = [envelope.source isEqualToString:localNumber]; if (shouldMarkMessageAsRead) { // Don't send a read receipt for messages sent by ourselves. - [incomingMessage markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:YES]; + [incomingMessage markAsReadWithTransaction:transaction sendReadReceipt:NO]; } TSQuotedMessage *_Nullable quotedMessage = incomingMessage.quotedMessage; @@ -1130,8 +1130,9 @@ NS_ASSUME_NONNULL_BEGIN [OWSReadReceiptManager.sharedManager applyEarlyReadReceiptsForIncomingMessage:incomingMessage transaction:transaction]; - [OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:incomingMessage - contactsManager:self.contactsManager]; + [[OWSDisappearingMessagesJob sharedJob] becomeConsistentWithConfigurationForMessage:incomingMessage + contactsManager:self.contactsManager + transaction:transaction]; // Update thread preview in inbox [thread touchWithTransaction:transaction]; diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.h b/SignalServiceKit/src/Messages/OWSMessageSender.h index 4539b9ff0..6b65f8f9b 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.h +++ b/SignalServiceKit/src/Messages/OWSMessageSender.h @@ -84,14 +84,6 @@ NS_SWIFT_NAME(MessageSender) success:(void (^)(void))successHandler failure:(void (^)(NSError *error))failureHandler; -/** - * Set local configuration to match that of the of `outgoingMessage`'s sender - * - * We do this because messages and async message latency make it possible for thread participants disappearing messags - * configuration to get out of sync. - */ -- (void)becomeConsistentWithDisappearingConfigurationForMessage:(TSOutgoingMessage *)outgoingMessage; - @end NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 266419d65..3040f0e59 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -1052,13 +1052,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [self sendSyncTranscriptForMessage:message]; } - [OWSDisappearingMessagesJob setExpirationForMessage:message]; -} - -- (void)becomeConsistentWithDisappearingConfigurationForMessage:(TSOutgoingMessage *)outgoingMessage -{ - [OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage - contactsManager:self.contactsManager]; + [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [[OWSDisappearingMessagesJob sharedJob] startExpirationForMessage:message + transaction:transaction]; + }]; } - (void)handleSendToMyself:(TSOutgoingMessage *)outgoingMessage diff --git a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m index 25587a5b5..a7f7392a4 100644 --- a/SignalServiceKit/src/Messages/OWSReadReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSReadReceiptManager.m @@ -431,11 +431,15 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE if (!readReceipt) { return; } - [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:YES]; + [message markAsReadWithTransaction:transaction sendReadReceipt:NO]; [readReceipt removeWithTransaction:transaction]; - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification - object:message]; + [transaction addCompletionQueue:nil + completionBlock:^{ + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification + object:message]; + }]; } - (void)processReadReceiptsFromLinkedDevice:(NSArray *)readReceiptProtos @@ -538,13 +542,18 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE } else { DDLogError(@"Marking %zd messages as read by linked device.", interactions.count); } + for (id possiblyRead in interactions) { - [possiblyRead markAsReadWithTransaction:transaction sendReadReceipt:wasLocal updateExpiration:YES]; + [possiblyRead markAsReadWithTransaction:transaction sendReadReceipt:wasLocal]; if ([possiblyRead isKindOfClass:[TSIncomingMessage class]]) { TSIncomingMessage *incomingMessage = (TSIncomingMessage *)possiblyRead; - [[NSNotificationCenter defaultCenter] postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification - object:incomingMessage]; + [transaction addCompletionQueue:nil + completionBlock:^{ + [[NSNotificationCenter defaultCenter] + postNotificationNameAsync:kIncomingMessageMarkedAsReadNotification + object:incomingMessage]; + }]; } } } diff --git a/SignalServiceKit/src/Messages/OWSReadTracking.h b/SignalServiceKit/src/Messages/OWSReadTracking.h index ed3dd27be..89122e8c5 100644 --- a/SignalServiceKit/src/Messages/OWSReadTracking.h +++ b/SignalServiceKit/src/Messages/OWSReadTracking.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // @class YapDatabaseReadWriteTransaction; @@ -21,10 +21,9 @@ - (BOOL)shouldAffectUnreadCounts; /** - * Used for *responding* to a remote read receipt or in response to user activity. + * Used both for *responding* to a remote read receipt and in response to the local user's activity. */ - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - sendReadReceipt:(BOOL)sendReadReceipt - updateExpiration:(BOOL)updateExpiration; + sendReadReceipt:(BOOL)sendReadReceipt; @end diff --git a/SignalServiceKit/src/Messages/TSCall.m b/SignalServiceKit/src/Messages/TSCall.m index a0b05c891..28e7e38d0 100644 --- a/SignalServiceKit/src/Messages/TSCall.m +++ b/SignalServiceKit/src/Messages/TSCall.m @@ -96,7 +96,6 @@ NSUInteger TSCallCurrentSchemaVersion = 1; - (void)markAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction sendReadReceipt:(BOOL)sendReadReceipt - updateExpiration:(BOOL)updateExpiration { OWSAssert(transaction); @@ -110,7 +109,7 @@ NSUInteger TSCallCurrentSchemaVersion = 1; [self saveWithTransaction:transaction]; [self touchThreadWithTransaction:transaction]; - // Ignore sendReadReceipt and updateExpiration; they don't apply to calls. + // Ignore sendReadReceipt - it doesn't apply to calls. } #pragma mark - Methods