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
pull/1/head
Michael Kirk 9 years ago committed by GitHub
parent 06538f6b46
commit 5b06b4351f

@ -16,7 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; - (instancetype)initWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp;
+ (nullable instancetype)firstWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp; + (nullable instancetype)firstWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp;
+ (void)registerIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database; + (void)asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database;
@end @end

@ -7,9 +7,9 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
NSString *const IndexOnSenderIdAndTimestamp = @"OWSReadReceiptIndexOnSenderIdAndTimestamp"; NSString *const OWSReadReceiptIndexOnSenderIdAndTimestamp = @"OWSReadReceiptIndexOnSenderIdAndTimestamp";
NSString *const TimestampColumn = @"timestamp"; NSString *const OWSReadReceiptColumnTimestamp = @"timestamp";
NSString *const SenderIdColumn = @"senderId"; NSString *const OWSReadReceiptColumnSenderId = @"senderId";
@implementation OWSReadReceipt @implementation OWSReadReceipt
@ -61,11 +61,11 @@ NSString *const SenderIdColumn = @"senderId";
return [behaviorsByPropertyKey copy]; return [behaviorsByPropertyKey copy];
} }
+ (void)registerIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database + (void)asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:(YapDatabase *)database
{ {
YapDatabaseSecondaryIndexSetup *setup = [YapDatabaseSecondaryIndexSetup new]; YapDatabaseSecondaryIndexSetup *setup = [YapDatabaseSecondaryIndexSetup new];
[setup addColumn:SenderIdColumn withType:YapDatabaseSecondaryIndexTypeText]; [setup addColumn:OWSReadReceiptColumnSenderId withType:YapDatabaseSecondaryIndexTypeText];
[setup addColumn:TimestampColumn withType:YapDatabaseSecondaryIndexTypeInteger]; [setup addColumn:OWSReadReceiptColumnTimestamp withType:YapDatabaseSecondaryIndexTypeInteger];
YapDatabaseSecondaryIndexHandler *handler = YapDatabaseSecondaryIndexHandler *handler =
[YapDatabaseSecondaryIndexHandler withObjectBlock:^(YapDatabaseReadTransaction *transaction, [YapDatabaseSecondaryIndexHandler withObjectBlock:^(YapDatabaseReadTransaction *transaction,
@ -75,24 +75,38 @@ NSString *const SenderIdColumn = @"senderId";
id object) { id object) {
if ([object isKindOfClass:[OWSReadReceipt class]]) { if ([object isKindOfClass:[OWSReadReceipt class]]) {
OWSReadReceipt *readReceipt = (OWSReadReceipt *)object; OWSReadReceipt *readReceipt = (OWSReadReceipt *)object;
dict[SenderIdColumn] = readReceipt.senderId; dict[OWSReadReceiptColumnSenderId] = readReceipt.senderId;
dict[TimestampColumn] = @(readReceipt.timestamp); dict[OWSReadReceiptColumnTimestamp] = @(readReceipt.timestamp);
} }
}]; }];
YapDatabaseSecondaryIndex *index = [[YapDatabaseSecondaryIndex alloc] initWithSetup:setup handler:handler]; 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 + (nullable instancetype)firstWithSenderId:(NSString *)senderId timestamp:(uint64_t)timestamp
{ {
__block OWSReadReceipt *foundReadReceipt; __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)]; YapDatabaseQuery *query = [YapDatabaseQuery queryWithFormat:queryFormat, senderId, @(timestamp)];
[[self dbConnection] readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) { [[self dbConnection] readWithBlock:^(YapDatabaseReadTransaction *_Nonnull transaction) {
[[transaction ext:IndexOnSenderIdAndTimestamp] [[transaction ext:OWSReadReceiptIndexOnSenderIdAndTimestamp]
enumerateKeysAndObjectsMatchingQuery:query enumerateKeysAndObjectsMatchingQuery:query
usingBlock:^(NSString *collection, NSString *key, id object, BOOL *stop) { usingBlock:^(NSString *collection, NSString *key, id object, BOOL *stop) {
if (![object isKindOfClass:[OWSReadReceipt class]]) { if (![object isKindOfClass:[OWSReadReceipt class]]) {

@ -24,6 +24,6 @@ extern NSString *TSSecondaryDevicesDatabaseViewExtensionName;
+ (BOOL)registerThreadDatabaseView; + (BOOL)registerThreadDatabaseView;
+ (BOOL)registerBuddyConversationDatabaseView; + (BOOL)registerBuddyConversationDatabaseView;
+ (BOOL)registerUnreadDatabaseView; + (BOOL)registerUnreadDatabaseView;
+ (BOOL)registerSecondaryDevicesDatabaseView; + (void)asyncRegisterSecondaryDevicesDatabaseView;
@end @end

@ -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 *viewGrouping =
[YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(YapDatabaseReadTransaction *_Nonnull transaction, [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(YapDatabaseReadTransaction *_Nonnull transaction,
NSString *_Nonnull collection, NSString *_Nonnull collection,
@ -260,8 +254,16 @@ NSString *TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesData
YapDatabaseView *view = YapDatabaseView *view =
[[YapDatabaseView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options]; [[YapDatabaseView alloc] initWithGrouping:viewGrouping sorting:viewSorting versionTag:@"3" options:options];
return [[TSStorageManager sharedManager].database registerExtension:view [[TSStorageManager sharedManager].database
withName:TSSecondaryDevicesDatabaseViewExtensionName]; 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 { + (NSDate *)localTimeReceiveDateForInteraction:(TSInteraction *)interaction {
@ -278,4 +280,16 @@ NSString *TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesData
return interactionDate; return interactionDate;
} }
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
@end @end

@ -109,25 +109,17 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
}; };
} }
- (void)setupDatabase { - (void)setupDatabase
{
// Register extensions which are essential for rendering threads synchronously
[TSDatabaseView registerThreadDatabaseView]; [TSDatabaseView registerThreadDatabaseView];
[TSDatabaseView registerBuddyConversationDatabaseView]; [TSDatabaseView registerBuddyConversationDatabaseView];
[TSDatabaseView registerUnreadDatabaseView]; [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"]; [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);
}
// Seeing this raise an exception-on-boot for some users, making it impossible to get any good data. // Register extensions which aren't essential for rendering threads async
@try { [TSDatabaseView asyncRegisterSecondaryDevicesDatabaseView];
[OWSReadReceipt registerIndexOnSenderIdAndTimestampWithDatabase:self.database]; [OWSReadReceipt asyncRegisterIndexOnSenderIdAndTimestampWithDatabase:self.database];
} @catch (NSException *exception) {
DDLogError(@"%@ Failed to register read receipt index with exception: %@ with reason: %@", self.tag, exception, exception.reason);
}
} }
- (void)protectSignalFiles { - (void)protectSignalFiles {

Loading…
Cancel
Save