From 5b06b4351f96d8be64368be0304c3f95e0c38401 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 28 Sep 2016 00:07:42 -0400 Subject: [PATCH] Fix timeout on launch for some users (#36) This would especially affect users with large databases on older devices. Some of these database extensions aren't strictly necessary to launch the app. Theoretically we could see weird read receipt behavior for the initial 10-30 seconds after the app is launched for first time. // FREEBIE --- src/Devices/OWSReadReceipt.h | 4 ++-- src/Devices/OWSReadReceipt.m | 36 +++++++++++++++++++++++----------- src/Storage/TSDatabaseView.h | 2 +- src/Storage/TSDatabaseView.m | 32 +++++++++++++++++++++--------- src/Storage/TSStorageManager.m | 22 +++++++-------------- 5 files changed, 58 insertions(+), 38 deletions(-) diff --git a/src/Devices/OWSReadReceipt.h b/src/Devices/OWSReadReceipt.h index 9cc49174f..d247dd539 100644 --- a/src/Devices/OWSReadReceipt.h +++ b/src/Devices/OWSReadReceipt.h @@ -16,8 +16,8 @@ NS_ASSUME_NONNULL_BEGIN - (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; + (nullable instancetype)firstWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; -+ (void)registerIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database; ++ (void)asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database; @end -NS_ASSUME_NONNULL_END \ No newline at end of file +NS_ASSUME_NONNULL_END diff --git a/src/Devices/OWSReadReceipt.m b/src/Devices/OWSReadReceipt.m index 06f1c776f..251eb6c09 100644 --- a/src/Devices/OWSReadReceipt.m +++ b/src/Devices/OWSReadReceipt.m @@ -7,9 +7,9 @@ NS_ASSUME_NONNULL_BEGIN -NSString *const IndexOnSenderIdAndTimestamp = @"OWSReadReceiptIndexOnSenderIdAndTimestamp"; -NSString *const TimestampColumn = @"timestamp"; -NSString *const SenderIdColumn = @"senderId"; +NSString *const OWSReadReceiptIndexOnSenderIdAndTimestamp = @"OWSReadReceiptIndexOnSenderIdAndTimestamp"; +NSString *const OWSReadReceiptColumnTimestamp = @"timestamp"; +NSString *const OWSReadReceiptColumnSenderId = @"senderId"; @implementation OWSReadReceipt @@ -61,11 +61,11 @@ NSString *const SenderIdColumn = @"senderId"; return [behaviorsByPropertyKey copy]; } -+ (void)registerIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database ++ (void)asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database { YapDatabaseSecondaryIndexSetup *setup = [YapDatabaseSecondaryIndexSetup new]; - [setup addColumn:SenderIdColumn withType:YapDatabaseSecondaryIndexTypeText]; - [setup addColumn:TimestampColumn withType:YapDatabaseSecondaryIndexTypeInteger]; + [setup addColumn:OWSReadReceiptColumnSenderId withType:YapDatabaseSecondaryIndexTypeText]; + [setup addColumn:OWSReadReceiptColumnTimestamp withType:YapDatabaseSecondaryIndexTypeInteger]; YapDatabaseSecondaryIndexHandler *handler = [YapDatabaseSecondaryIndexHandler withObjectBlock:^(YapDatabaseReadTransaction *transaction, @@ -75,24 +75,38 @@ NSString *const SenderIdColumn = @"senderId"; id object) { if ([object isKindOfClass:[OWSReadReceipt class]]) { OWSReadReceipt *readReceipt = (OWSReadReceipt *)object; - dict[SenderIdColumn] = readReceipt.senderId; - dict[TimestampColumn] = @(readReceipt.timestamp); + dict[OWSReadReceiptColumnSenderId] = readReceipt.senderId; + dict[OWSReadReceiptColumnTimestamp] = @(readReceipt.timestamp); } }]; YapDatabaseSecondaryIndex *index = [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler]; - [database registerExtension:index withName:IndexOnSenderIdAndTimestamp]; + + [database + asyncRegisterExtension:index + withName:OWSReadReceiptIndexOnSenderIdAndTimestamp + completionBlock:^(BOOL ready) { + if (ready) { + DDLogDebug(@"%@ Successfully set up extension: %@", + self.tag, + OWSReadReceiptIndexOnSenderIdAndTimestamp); + } else { + DDLogError( + @"%@ Unable to setup extension: %@", self.tag, OWSReadReceiptIndexOnSenderIdAndTimestamp); + } + }]; } + (nullable instancetype)firstWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp { __block OWSReadReceipt *foundReadReceipt; - NSString *queryFormat = [NSString stringWithFormat:@"WHERE %@ = ? AND %@ = ?", SenderIdColumn, TimestampColumn]; + NSString *queryFormat = [NSString + stringWithFormat:@"WHERE %@ = ? AND %@ = ?", OWSReadReceiptColumnSenderId, OWSReadReceiptColumnTimestamp]; YapDatabaseQuery *query = [YapDatabaseQuery queryWithFormat:queryFormat, senderId, @(timestamp)]; [[self dbConnection] readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { - [[transaction ext:IndexOnSenderIdAndTimestamp] + [[transaction ext:OWSReadReceiptIndexOnSenderIdAndTimestamp] enumerateKeysAndObjectsMatchingQuery:query usingBlock:^(NSString *collection, NSString *key, id object, BOOL *stop) { if (![object isKindOfClass:[OWSReadReceipt class]]) { diff --git a/src/Storage/TSDatabaseView.h b/src/Storage/TSDatabaseView.h index 584483ded..9fbb72541 100644 --- a/src/Storage/TSDatabaseView.h +++ b/src/Storage/TSDatabaseView.h @@ -24,6 +24,6 @@ extern NSString *TSSecondaryDevicesDatabaseViewExtensionName; + (BOOL)registerThreadDatabaseView; + (BOOL)registerBuddyConversationDatabaseView; + (BOOL)registerUnreadDatabaseView; -+ (BOOL)registerSecondaryDevicesDatabaseView; ++ (void)asyncRegisterSecondaryDevicesDatabaseView; @end diff --git a/src/Storage/TSDatabaseView.m b/src/Storage/TSDatabaseView.m index 40b533259..15db56bae 100644 --- a/src/Storage/TSDatabaseView.m +++ b/src/Storage/TSDatabaseView.m @@ -209,14 +209,8 @@ NSString *TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesData }]; } -+ (BOOL)registerSecondaryDevicesDatabaseView ++ (void)asyncRegisterSecondaryDevicesDatabaseView { - YapDatabaseView *existingView = - [[TSStorageManager sharedManager].database registeredExtension:TSSecondaryDevicesDatabaseViewExtensionName]; - if (existingView) { - return YES; - } - YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(YapDatabaseReadTransaction *_Nonnull transaction, NSString *_Nonnull collection, @@ -260,8 +254,16 @@ NSString *TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesData YapDatabaseView *view = [[YapDatabaseView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options]; - return [[TSStorageManager sharedManager].database registerExtension:view - withName:TSSecondaryDevicesDatabaseViewExtensionName]; + [[TSStorageManager sharedManager].database + asyncRegisterExtension:view + withName:TSSecondaryDevicesGroup + completionBlock:^(BOOL ready) { + if (ready) { + DDLogDebug(@"%@ Successfully set up extension: %@", self.tag, TSSecondaryDevicesGroup); + } else { + DDLogError(@"%@ Unable to setup extension: %@", self.tag, TSSecondaryDevicesGroup); + } + }]; } + (NSDate *)localTimeReceiveDateForInteraction:(TSInteraction *)interaction { @@ -278,4 +280,16 @@ NSString *TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesData return interactionDate; } +#pragma mark - Logging + ++ (NSString *)tag +{ + return [NSString stringWithFormat:@"[%@]", self.class]; +} + +- (NSString *)tag +{ + return self.class.tag; +} + @end diff --git a/src/Storage/TSStorageManager.m b/src/Storage/TSStorageManager.m index 881e25960..f9b39857a 100644 --- a/src/Storage/TSStorageManager.m +++ b/src/Storage/TSStorageManager.m @@ -109,25 +109,17 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass"; }; } -- (void)setupDatabase { +- (void)setupDatabase +{ + // Register extensions which are essential for rendering threads synchronously [TSDatabaseView registerThreadDatabaseView]; [TSDatabaseView registerBuddyConversationDatabaseView]; [TSDatabaseView registerUnreadDatabaseView]; - [TSDatabaseView registerSecondaryDevicesDatabaseView]; - - // Seeing this raise an exception-on-boot for some users, making it impossible to get any good data. - @try { - [self.database registerExtension:[TSDatabaseSecondaryIndexes registerTimeStampIndex] withName:@"idx"]; - } @catch (NSException *exception) { - DDLogError(@"%@ Failed to register timetamp index with exception: %@ with reason: %@", self.tag, exception, exception.reason); - } + [self.database registerExtension:[TSDatabaseSecondaryIndexes registerTimeStampIndex] withName:@"idx"]; - // Seeing this raise an exception-on-boot for some users, making it impossible to get any good data. - @try { - [OWSReadReceipt registerIndexOnSenderIdAndTimestampWithDatabase:self.database]; - } @catch (NSException *exception) { - DDLogError(@"%@ Failed to register read receipt index with exception: %@ with reason: %@", self.tag, exception, exception.reason); - } + // Register extensions which aren't essential for rendering threads async + [TSDatabaseView asyncRegisterSecondaryDevicesDatabaseView]; + [OWSReadReceipt asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:self.database]; } - (void)protectSignalFiles {