From 45d6250aeec7945a31f4f84e57c0652436fbd21f Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 11 Oct 2018 12:59:40 -0400 Subject: [PATCH] Send delivery receipts. --- .../src/Messages/OWSDeliveryReceiptManager.m | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/SignalServiceKit/src/Messages/OWSDeliveryReceiptManager.m b/SignalServiceKit/src/Messages/OWSDeliveryReceiptManager.m index f0d12f195..2120d07a7 100644 --- a/SignalServiceKit/src/Messages/OWSDeliveryReceiptManager.m +++ b/SignalServiceKit/src/Messages/OWSDeliveryReceiptManager.m @@ -110,11 +110,11 @@ NSString *const kDeliveryReceiptManagerCollection = @"kDeliveryReceiptManagerCol usingBlock:^(NSString *key, id object, BOOL *stop) { NSString *recipientId = key; NSSet *timestamps = object; - deliveryReceiptMap[recipientId] = timestamps; + deliveryReceiptMap[recipientId] = [timestamps copy]; }]; }]; - BOOL didWork = NO; + NSMutableArray *sendPromises = [NSMutableArray array]; for (NSString *recipientId in deliveryReceiptMap) { NSSet *timestamps = deliveryReceiptMap[recipientId]; @@ -128,41 +128,47 @@ NSString *const kDeliveryReceiptManagerCollection = @"kDeliveryReceiptManagerCol [OWSReceiptsForSenderMessage deliveryReceiptsForSenderMessageWithThread:thread messageTimestamps:timestamps.allObjects]; - [self.messageSender enqueueMessage:message - success:^{ - OWSLogInfo(@"Successfully sent %lu delivery receipts to sender.", (unsigned long)timestamps.count); - } - failure:^(NSError *error) { - OWSLogError(@"Failed to send delivery receipts to sender with error: %@", error); - }]; + AnyPromise *sendPromise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { + [self.messageSender enqueueMessage:message + success:^{ + OWSLogInfo(@"Successfully sent %lu delivery receipts to sender.", (unsigned long)timestamps.count); - didWork = YES; - } + [self dequeueDeliveryReceiptsWithRecipientId:recipientId timestamps:timestamps]; - // Now that they've been processed, remove all enqueued delivery receipts. - // - // NOTE: we don't need to worry about race conditions; this - // collection will only be mutated on serialQueue. - [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction removeAllObjectsInCollection:kDeliveryReceiptManagerCollection]; - }]; + // The value doesn't matter, we just need any non-NSError value. + resolve(@(1)); + } + failure:^(NSError *error) { + OWSLogError(@"Failed to send delivery receipts to sender with error: %@", error); - if (!didWork) { + resolve(error); + }]; + }]; + [sendPromises addObject:sendPromise]; + } + + if (sendPromises.count < 1) { + // No work to do; abort. self.isProcessing = NO; return; } - // Wait N seconds before processing delivery receipts again. - // This allows time for a batch to accumulate. - // - // We want a value high enough to allow us to effectively de-duplicate, - // delivery receipts without being so high that we risk not sending delivery - // receipts due to app exit. - const CGFloat kProcessingFrequencySeconds = 3.f; - dispatch_after( - dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kProcessingFrequencySeconds * NSEC_PER_SEC)), self.serialQueue, ^{ - [self process]; - }); + AnyPromise *completionPromise = PMKJoin(sendPromises); + completionPromise.always(^() { + // Wait N seconds before processing delivery receipts again. + // This allows time for a batch to accumulate. + // + // We want a value high enough to allow us to effectively de-duplicate, + // delivery receipts without being so high that we risk not sending delivery + // receipts due to app exit. + const CGFloat kProcessingFrequencySeconds = 3.f; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(kProcessingFrequencySeconds * NSEC_PER_SEC)), + self.serialQueue, + ^{ + [self process]; + }); + }); + [completionPromise retainUntilComplete]; } - (void)envelopeWasReceived:(SSKProtoEnvelope *)envelope {