Send "sent message transcript" sync messages at the _end_ of a send, not after the first recipient is sent.

pull/1/head
Matthew Chen 7 years ago
parent 9cb7f1a4f8
commit 86e22edcb1

@ -67,7 +67,7 @@ NS_ASSUME_NONNULL_BEGIN
[sentBuilder setMessage:dataMessage]; [sentBuilder setMessage:dataMessage];
[sentBuilder setExpirationStartTimestamp:self.message.timestamp]; [sentBuilder setExpirationStartTimestamp:self.message.timestamp];
for (NSString *recipientId in self.message.recipientIds) { for (NSString *recipientId in self.message.sentRecipientIds) {
TSOutgoingMessageRecipientState *_Nullable recipientState = TSOutgoingMessageRecipientState *_Nullable recipientState =
[self.message recipientStateForRecipientId:recipientId]; [self.message recipientStateForRecipientId:recipientId];
if (!recipientState) { if (!recipientState) {
@ -75,6 +75,7 @@ NS_ASSUME_NONNULL_BEGIN
continue; continue;
} }
if (recipientState.state != OWSOutgoingMessageRecipientStateSent) { if (recipientState.state != OWSOutgoingMessageRecipientStateSent) {
OWSFailDebug(@"unexpected recipient state for: %@", recipientId);
continue; continue;
} }

@ -113,6 +113,7 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
@property (readonly) TSOutgoingMessageState messageState; @property (readonly) TSOutgoingMessageState messageState;
@property (readonly) BOOL wasDeliveredToAnyRecipient; @property (readonly) BOOL wasDeliveredToAnyRecipient;
@property (readonly) BOOL wasSentToAnyRecipient;
@property (atomic, readonly) BOOL hasSyncedTranscript; @property (atomic, readonly) BOOL hasSyncedTranscript;
@property (atomic, readonly) NSString *customMessage; @property (atomic, readonly) NSString *customMessage;
@ -155,7 +156,10 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
// All recipients of this message who we are currently trying to send to (queued, uploading or during send). // All recipients of this message who we are currently trying to send to (queued, uploading or during send).
- (NSArray<NSString *> *)sendingRecipientIds; - (NSArray<NSString *> *)sendingRecipientIds;
// All recipients of this message to whom it has been sent and delivered. // All recipients of this message to whom it has been sent (and possibly delivered or read).
- (NSArray<NSString *> *)sentRecipientIds;
// All recipients of this message to whom it has been sent and delivered (and possibly read).
- (NSArray<NSString *> *)deliveredRecipientIds; - (NSArray<NSString *> *)deliveredRecipientIds;
// All recipients of this message to whom it has been sent, delivered and read. // All recipients of this message to whom it has been sent, delivered and read.

@ -405,6 +405,14 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
return (self.hasLegacyMessageState && self.legacyWasDelivered && self.messageState == TSOutgoingMessageStateSent); return (self.hasLegacyMessageState && self.legacyWasDelivered && self.messageState == TSOutgoingMessageStateSent);
} }
- (BOOL)wasSentToAnyRecipient
{
if ([self sentRecipientIds].count > 0) {
return YES;
}
return (self.hasLegacyMessageState && self.messageState == TSOutgoingMessageStateSent);
}
+ (TSOutgoingMessageState)messageStateForRecipientStates:(NSArray<TSOutgoingMessageRecipientState *> *)recipientStates + (TSOutgoingMessageState)messageStateForRecipientStates:(NSArray<TSOutgoingMessageRecipientState *> *)recipientStates
{ {
OWSAssertDebug(recipientStates); OWSAssertDebug(recipientStates);
@ -509,6 +517,18 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
return result; return result;
} }
- (NSArray<NSString *> *)sentRecipientIds
{
NSMutableArray<NSString *> *result = [NSMutableArray new];
for (NSString *recipientId in self.recipientStateMap) {
TSOutgoingMessageRecipientState *recipientState = self.recipientStateMap[recipientId];
if (recipientState.state == OWSOutgoingMessageRecipientStateSent) {
[result addObject:recipientId];
}
}
return result;
}
- (NSArray<NSString *> *)deliveredRecipientIds - (NSArray<NSString *> *)deliveredRecipientIds
{ {
NSMutableArray<NSString *> *result = [NSMutableArray new]; NSMutableArray<NSString *> *result = [NSMutableArray new];

@ -619,11 +619,26 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
- (void)sendMessageToService:(TSOutgoingMessage *)message - (void)sendMessageToService:(TSOutgoingMessage *)message
senderCertificate:(nullable SMKSenderCertificate *)senderCertificate senderCertificate:(nullable SMKSenderCertificate *)senderCertificate
success:(void (^)(void))successHandler success:(void (^)(void))successHandlerParam
failure:(RetryableFailureHandler)failureHandler failure:(RetryableFailureHandler)failureHandlerParam
{ {
AssertIsOnSendingQueue(); AssertIsOnSendingQueue();
void (^successHandler)(void) = ^() {
dispatch_async([OWSDispatch sendingQueue], ^{
[self handleMessageSentLocally:message senderCertificate:senderCertificate];
});
successHandlerParam();
};
void (^failureHandler)(NSError *) = ^(NSError *error) {
if (message.wasSentToAnyRecipient) {
dispatch_async([OWSDispatch sendingQueue], ^{
[self handleMessageSentLocally:message senderCertificate:senderCertificate];
});
}
failureHandlerParam(error);
};
TSThread *_Nullable thread = message.thread; TSThread *_Nullable thread = message.thread;
// In the "self-send" special case, we ony need to send a sync message with a delivery receipt. // In the "self-send" special case, we ony need to send a sync message with a delivery receipt.
@ -638,9 +653,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
transaction:transaction]; transaction:transaction];
} }
}]; }];
[self handleMessageSentLocally:message senderCertificate:senderCertificate];
successHandler(); successHandler();
return; return;
} }
@ -1103,8 +1115,6 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
[SignalRecipient markRecipientAsRegisteredAndGet:recipient.recipientId transaction:transaction]; [SignalRecipient markRecipientAsRegisteredAndGet:recipient.recipientId transaction:transaction];
}]; }];
[self handleMessageSentLocally:messageSend.message
senderCertificate:messageSend.unidentifiedAccess.senderCertificate];
messageSend.success(); messageSend.success();
}); });
} }
@ -1273,6 +1283,10 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
if (message.shouldSyncTranscript) { if (message.shouldSyncTranscript) {
// TODO: I suspect we shouldn't optimistically set hasSyncedTranscript. // TODO: I suspect we shouldn't optimistically set hasSyncedTranscript.
// We could set this in a success handler for [sendSyncTranscriptForMessage:]. // We could set this in a success handler for [sendSyncTranscriptForMessage:].
// TODO: We might send to a recipient, then to another recipient on retry.
// To ensure desktop receives all "delivery status" info, we might
// want to send a transcript after every send that reaches _any_
// new recipients.
[self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[message updateWithHasSyncedTranscript:YES transaction:transaction]; [message updateWithHasSyncedTranscript:YES transaction:transaction];
}]; }];

Loading…
Cancel
Save