Handle mismatched/stale devices on session queue

The session state should never be manipulated concurrently.

// FREEBIE
pull/1/head
Michael Kirk 9 years ago
parent 773b09b015
commit 2d93b8c6ec

@ -42,6 +42,13 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
void AssertIsOnSendingQueue()
{
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(10, 0)) {
dispatch_assert_queue([OWSDispatch sendingQueue]);
} // else, skip assert as it's a development convenience.
}
/** /**
* OWSSendMessageOperation encapsulates all the work associated with sending a message, e.g. uploading attachments, * OWSSendMessageOperation encapsulates all the work associated with sending a message, e.g. uploading attachments,
* getting proper keys, and retrying upon failure. * getting proper keys, and retrying upon failure.
@ -724,6 +731,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
failure:(RetryableFailureHandler)failureHandler failure:(RetryableFailureHandler)failureHandler
{ {
DDLogDebug(@"%@ sending message to service: %@", self.tag, message.debugDescription); DDLogDebug(@"%@ sending message to service: %@", self.tag, message.debugDescription);
AssertIsOnSendingQueue();
if ([TSPreKeyManager isAppLockedDueToPreKeyUpdateFailures]) { if ([TSPreKeyManager isAppLockedDueToPreKeyUpdateFailures]) {
OWSAnalyticsError(@"Message send failed due to prekey update failures"); OWSAnalyticsError(@"Message send failed due to prekey update failures");
@ -857,8 +865,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return failureHandler(error, YES); return failureHandler(error, YES);
} }
[self handleMismatchedDevices:serializedResponse recipient:recipient]; [self handleMismatchedDevices:serializedResponse recipient:recipient completion:retrySend];
retrySend();
break; break;
} }
case 410: { case 410: {
@ -871,8 +878,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return failureHandler(error, YES); return failureHandler(error, YES);
} }
[self handleStaleDevicesWithResponse:responseData recipientId:recipient.uniqueId]; [self handleStaleDevicesWithResponse:responseData
retrySend(); recipientId:recipient.uniqueId
completion:retrySend];
break; break;
} }
default: default:
@ -882,24 +890,29 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
}]; }];
} }
- (void)handleMismatchedDevices:(NSDictionary *)dictionary recipient:(SignalRecipient *)recipient - (void)handleMismatchedDevices:(NSDictionary *)dictionary
recipient:(SignalRecipient *)recipient
completion:(void (^)())completionHandler
{ {
NSArray *extraDevices = [dictionary objectForKey:@"extraDevices"]; NSArray *extraDevices = [dictionary objectForKey:@"extraDevices"];
NSArray *missingDevices = [dictionary objectForKey:@"missingDevices"]; NSArray *missingDevices = [dictionary objectForKey:@"missingDevices"];
if (extraDevices && extraDevices.count > 0) { dispatch_async([OWSDispatch sessionStoreQueue], ^{
for (NSNumber *extraDeviceId in extraDevices) { if (extraDevices && extraDevices.count > 0) {
[self.storageManager deleteSessionForContact:recipient.uniqueId deviceId:extraDeviceId.intValue]; for (NSNumber *extraDeviceId in extraDevices) {
} [self.storageManager deleteSessionForContact:recipient.uniqueId deviceId:extraDeviceId.intValue];
}
[recipient removeDevices:[NSSet setWithArray:extraDevices]]; [recipient removeDevices:[NSSet setWithArray:extraDevices]];
} }
if (missingDevices && missingDevices.count > 0) { if (missingDevices && missingDevices.count > 0) {
[recipient addDevices:[NSSet setWithArray:missingDevices]]; [recipient addDevices:[NSSet setWithArray:missingDevices]];
} }
[recipient save]; [recipient save];
completionHandler();
});
} }
- (void)handleMessageSentLocally:(TSOutgoingMessage *)message - (void)handleMessageSentLocally:(TSOutgoingMessage *)message
@ -1173,7 +1186,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
} }
} }
- (void)handleStaleDevicesWithResponse:(NSData *)responseData recipientId:(NSString *)identifier - (void)handleStaleDevicesWithResponse:(NSData *)responseData
recipientId:(NSString *)identifier
completion:(void (^)())completionHandler
{ {
dispatch_async([OWSDispatch sendingQueue], ^{ dispatch_async([OWSDispatch sendingQueue], ^{
NSDictionary *serialization = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; NSDictionary *serialization = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil];
@ -1183,10 +1198,13 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
return; return;
} }
for (NSUInteger i = 0; i < [devices count]; i++) { dispatch_async([OWSDispatch sessionStoreQueue], ^{
int deviceNumber = [devices[i] intValue]; for (NSUInteger i = 0; i < [devices count]; i++) {
[[TSStorageManager sharedManager] deleteSessionForContact:identifier deviceId:deviceNumber]; int deviceNumber = [devices[i] intValue];
} [[TSStorageManager sharedManager] deleteSessionForContact:identifier deviceId:deviceNumber];
}
completionHandler();
});
}); });
} }

Loading…
Cancel
Save