Recreate message database view when message mappings are corrupt.

pull/1/head
Matthew Chen 7 years ago
parent 1e75b6518b
commit 0a7b3537b5

@ -441,6 +441,8 @@ typedef enum : NSUInteger {
{ {
OWSAssert(thread); OWSAssert(thread);
DDLogInfo(@"%@ configureForThread.", self.logTag);
_thread = thread; _thread = thread;
self.actionOnOpen = action; self.actionOnOpen = action;
self.focusMessageIdOnOpen = focusMessageId; self.focusMessageIdOnOpen = focusMessageId;
@ -3224,7 +3226,7 @@ typedef enum : NSUInteger {
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); DDLogVerbose(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
if (self.shouldObserveDBModifications) { if (self.shouldObserveDBModifications) {
// External database modifications can't be converted into incremental updates, // External database modifications can't be converted into incremental updates,
@ -3233,14 +3235,12 @@ typedef enum : NSUInteger {
// //
// We don't need to do this if we're not observing db modifications since we'll // We don't need to do this if we're not observing db modifications since we'll
// do it when we resume. // do it when we resume.
[self hardResetMappings]; [self resetMappings];
} }
} }
- (void)uiDatabaseWillUpdate:(NSNotification *)notification - (void)uiDatabaseWillUpdate:(NSNotification *)notification
{ {
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
// HACK to work around radar #28167779 // HACK to work around radar #28167779
// "UICollectionView performBatchUpdates can trigger a crash if the collection view is flagged for layout" // "UICollectionView performBatchUpdates can trigger a crash if the collection view is flagged for layout"
// more: https://github.com/PSPDFKit-labs/radar.apple.com/tree/master/28167779%20-%20CollectionViewBatchingIssue // more: https://github.com/PSPDFKit-labs/radar.apple.com/tree/master/28167779%20-%20CollectionViewBatchingIssue
@ -3257,10 +3257,12 @@ typedef enum : NSUInteger {
{ {
OWSAssertIsOnMainThread(); OWSAssertIsOnMainThread();
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); DDLogInfo(@"%@ uiDatabaseDidUpdate, connection snapshot: %llu, mappings snapshot: %llu.",
self.logTag,
self.uiDatabaseConnection.snapshot,
self.messageMappings.snapshotOfLastUpdate);
if (!self.shouldObserveDBModifications) { if (!self.shouldObserveDBModifications) {
DDLogInfo(@"%@ %s ignoring", self.logTag, __PRETTY_FUNCTION__);
return; return;
} }
@ -3299,9 +3301,6 @@ typedef enum : NSUInteger {
return; return;
} }
DDLogInfo(@"%@ uiDatabaseDidUpdate notifications: %@", self.logTag, notifications);
NSArray<YapDatabaseViewSectionChange *> *sectionChanges = nil; NSArray<YapDatabaseViewSectionChange *> *sectionChanges = nil;
NSArray<YapDatabaseViewRowChange *> *rowChanges = nil; NSArray<YapDatabaseViewRowChange *> *rowChanges = nil;
[[self.uiDatabaseConnection ext:TSMessageDatabaseViewExtensionName] getSectionChanges:&sectionChanges [[self.uiDatabaseConnection ext:TSMessageDatabaseViewExtensionName] getSectionChanges:&sectionChanges
@ -3369,7 +3368,7 @@ typedef enum : NSUInteger {
// These errors seems to be very rare; they can only be reproduced // These errors seems to be very rare; they can only be reproduced
// using the more extreme actions in the debug UI. // using the more extreme actions in the debug UI.
OWSFail(@"%@ hasMalformedRowChange", self.logTag); OWSFail(@"%@ hasMalformedRowChange", self.logTag);
[self hardResetMappings]; [self resetMappings];
[self updateLastVisibleTimestamp]; [self updateLastVisibleTimestamp];
[self scrollToBottomAnimated:NO]; [self scrollToBottomAnimated:NO];
return; return;
@ -3379,7 +3378,7 @@ typedef enum : NSUInteger {
if (![self reloadViewItems]) { if (![self reloadViewItems]) {
// These errors are rare. // These errors are rare.
OWSFail(@"%@ could not reload view items; hard resetting message mappings.", self.logTag); OWSFail(@"%@ could not reload view items; hard resetting message mappings.", self.logTag);
[self hardResetMappings]; [self resetMappings];
[self updateLastVisibleTimestamp]; [self updateLastVisibleTimestamp];
[self scrollToBottomAnimated:NO]; [self scrollToBottomAnimated:NO];
return; return;
@ -3400,8 +3399,7 @@ typedef enum : NSUInteger {
for (YapDatabaseViewRowChange *rowChange in rowChanges) { for (YapDatabaseViewRowChange *rowChange in rowChanges) {
switch (rowChange.type) { switch (rowChange.type) {
case YapDatabaseViewChangeDelete: { case YapDatabaseViewChangeDelete: {
DDLogInfo(@"%@ YapDatabaseViewChangeDelete collectionKey: %@, indexPath: %@, finalIndex: %lu", DDLogVerbose(@"YapDatabaseViewChangeDelete collectionKey: %@, indexPath: %@, finalIndex: %lu",
self.logTag,
rowChange.collectionKey, rowChange.collectionKey,
rowChange.indexPath, rowChange.indexPath,
(unsigned long)rowChange.finalIndex); (unsigned long)rowChange.finalIndex);
@ -3411,8 +3409,7 @@ typedef enum : NSUInteger {
break; break;
} }
case YapDatabaseViewChangeInsert: { case YapDatabaseViewChangeInsert: {
DDLogInfo(@"%@ YapDatabaseViewChangeInsert collectionKey: %@, newIndexPath: %@, finalIndex: %lu", DDLogVerbose(@"YapDatabaseViewChangeInsert collectionKey: %@, newIndexPath: %@, finalIndex: %lu",
self.logTag,
rowChange.collectionKey, rowChange.collectionKey,
rowChange.newIndexPath, rowChange.newIndexPath,
(unsigned long)rowChange.finalIndex); (unsigned long)rowChange.finalIndex);
@ -3429,9 +3426,8 @@ typedef enum : NSUInteger {
break; break;
} }
case YapDatabaseViewChangeMove: { case YapDatabaseViewChangeMove: {
DDLogInfo(@"%@ YapDatabaseViewChangeMove collectionKey: %@, indexPath: %@, newIndexPath: %@, " DDLogVerbose(@"YapDatabaseViewChangeMove collectionKey: %@, indexPath: %@, newIndexPath: %@, "
@"finalIndex: %lu", @"finalIndex: %lu",
self.logTag,
rowChange.collectionKey, rowChange.collectionKey,
rowChange.indexPath, rowChange.indexPath,
rowChange.newIndexPath, rowChange.newIndexPath,
@ -3440,8 +3436,7 @@ typedef enum : NSUInteger {
break; break;
} }
case YapDatabaseViewChangeUpdate: { case YapDatabaseViewChangeUpdate: {
DDLogInfo(@"%@ YapDatabaseViewChangeUpdate collectionKey: %@, indexPath: %@, finalIndex: %lu", DDLogVerbose(@"YapDatabaseViewChangeUpdate collectionKey: %@, indexPath: %@, finalIndex: %lu",
self.logTag,
rowChange.collectionKey, rowChange.collectionKey,
rowChange.indexPath, rowChange.indexPath,
(unsigned long)rowChange.finalIndex); (unsigned long)rowChange.finalIndex);
@ -3452,7 +3447,7 @@ typedef enum : NSUInteger {
} }
}; };
DDLogInfo(@"%@ viewItems.count: %zd -> %zd", self.logTag, oldViewItemCount, self.viewItems.count); DDLogVerbose(@"self.viewItems.count: %zd -> %zd", oldViewItemCount, self.viewItems.count);
BOOL shouldAnimateUpdates = [self shouldAnimateRowUpdates:rowChanges oldViewItemCount:oldViewItemCount]; BOOL shouldAnimateUpdates = [self shouldAnimateRowUpdates:rowChanges oldViewItemCount:oldViewItemCount];
void (^batchUpdatesCompletion)(BOOL) = ^(BOOL finished) { void (^batchUpdatesCompletion)(BOOL) = ^(BOOL finished) {
@ -4828,14 +4823,6 @@ typedef enum : NSUInteger {
[self updateMessageMappingRangeOptions]; [self updateMessageMappingRangeOptions];
} }
- (void)hardResetMappings
{
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
[self createNewMessageMappings];
[self resetMappings];
}
- (void)resetMappings - (void)resetMappings
{ {
// If we're entering "active" mode (e.g. view is visible and app is in foreground), // If we're entering "active" mode (e.g. view is visible and app is in foreground),
@ -4888,6 +4875,11 @@ typedef enum : NSUInteger {
// Returns NO on error. // Returns NO on error.
- (BOOL)reloadViewItems - (BOOL)reloadViewItems
{ {
DDLogInfo(@"%@ reloadViewItems, connection snapshot: %llu, mappings snapshot: %llu.",
self.logTag,
self.uiDatabaseConnection.snapshot,
self.messageMappings.snapshotOfLastUpdate);
NSMutableArray<ConversationViewItem *> *viewItems = [NSMutableArray new]; NSMutableArray<ConversationViewItem *> *viewItems = [NSMutableArray new];
NSMutableDictionary<NSString *, ConversationViewItem *> *viewItemCache = [NSMutableDictionary new]; NSMutableDictionary<NSString *, ConversationViewItem *> *viewItemCache = [NSMutableDictionary new];
@ -4934,6 +4926,14 @@ typedef enum : NSUInteger {
} }
}]; }];
// Flag to ensure that we only increment once per launch.
static BOOL hasIncrementedDatabaseView = NO;
if (hasError && !hasIncrementedDatabaseView) {
DDLogWarn(@"%@ incrementing version of: %@", self.logTag, TSMessageDatabaseViewExtensionName);
[OWSPrimaryStorage incrementVersionOfDatabaseExtension:TSMessageDatabaseViewExtensionName];
hasIncrementedDatabaseView = YES;
}
// Update the "break" properties (shouldShowDate and unreadIndicator) of the view items. // Update the "break" properties (shouldShowDate and unreadIndicator) of the view items.
BOOL shouldShowDateOnNextViewItem = YES; BOOL shouldShowDateOnNextViewItem = YES;
uint64_t previousViewItemTimestamp = 0; uint64_t previousViewItemTimestamp = 0;

@ -132,6 +132,7 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage)
- (void)updateUIDatabaseConnectionToLatest - (void)updateUIDatabaseConnectionToLatest
{ {
OWSAssertIsOnMainThread();
// Notify observers we're about to update the database connection // Notify observers we're about to update the database connection
[[NSNotificationCenter defaultCenter] postNotificationName:OWSUIDatabaseConnectionWillUpdateNotification object:self.dbNotificationObject]; [[NSNotificationCenter defaultCenter] postNotificationName:OWSUIDatabaseConnectionWillUpdateNotification object:self.dbNotificationObject];

Loading…
Cancel
Save