Merge branch 'charlesmchen/conversationViewCrashLogging'

pull/1/head
Matthew Chen 7 years ago
commit 56e3ff14fe

@ -38,7 +38,7 @@
</dict> </dict>
</array> </array>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.29.0.6</string> <string>2.29.0.9</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>LOGS_EMAIL</key> <key>LOGS_EMAIL</key>

@ -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;
@ -455,29 +457,11 @@ typedef enum : NSUInteger {
[self ensureDynamicInteractions]; [self ensureDynamicInteractions];
[[OWSPrimaryStorage sharedManager] updateUIDatabaseConnectionToLatest]; [[OWSPrimaryStorage sharedManager] updateUIDatabaseConnectionToLatest];
if (thread.uniqueId.length > 0) { [self createNewMessageMappings];
self.messageMappings = [[YapDatabaseViewMappings alloc] initWithGroups:@[ thread.uniqueId ] if (![self reloadViewItems]) {
view:TSMessageDatabaseViewExtensionName]; OWSFail(@"%@ failed to reload view items in configureForThread.", self.logTag);
} else {
OWSFail(@"uniqueId unexpectedly empty for thread: %@", thread);
self.messageMappings =
[[YapDatabaseViewMappings alloc] initWithGroups:@[] view:TSMessageDatabaseViewExtensionName];
return;
} }
// Cells' appearance can depend on adjacent cells in both directions.
[self.messageMappings setCellDrawingDependencyOffsets:[NSSet setWithArray:@[
@(-1),
@(+1),
]]
forGroup:self.thread.uniqueId];
// We need to impose the range restrictions on the mappings immediately to avoid
// doing a great deal of unnecessary work and causing a perf hotspot.
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[self.messageMappings updateWithTransaction:transaction];
}];
[self updateMessageMappingRangeOptions];
[self updateShouldObserveDBModifications]; [self updateShouldObserveDBModifications];
self.reloadTimer = [NSTimer weakScheduledTimerWithTimeInterval:1.f self.reloadTimer = [NSTimer weakScheduledTimerWithTimeInterval:1.f
@ -814,7 +798,9 @@ typedef enum : NSUInteger {
// Avoid layout corrupt issues and out-of-date message subtitles. // Avoid layout corrupt issues and out-of-date message subtitles.
self.lastReloadDate = [NSDate new]; self.lastReloadDate = [NSDate new];
self.collapseCutoffDate = [NSDate new]; self.collapseCutoffDate = [NSDate new];
[self reloadViewItems]; if (![self reloadViewItems]) {
OWSFail(@"%@ failed to reload view items in resetContentAndLayout.", self.logTag);
}
[self.collectionView.collectionViewLayout invalidateLayout]; [self.collectionView.collectionViewLayout invalidateLayout];
[self.collectionView reloadData]; [self.collectionView reloadData];
} }
@ -1771,7 +1757,6 @@ typedef enum : NSUInteger {
[self.messageMappings setRangeOptions:rangeOptions forGroup:self.thread.uniqueId]; [self.messageMappings setRangeOptions:rangeOptions forGroup:self.thread.uniqueId];
[self updateShowLoadMoreHeader]; [self updateShowLoadMoreHeader];
self.collapseCutoffDate = [NSDate new]; self.collapseCutoffDate = [NSDate new];
[self reloadViewItems];
} }
#pragma mark Bubble User Actions #pragma mark Bubble User Actions
@ -3378,14 +3363,21 @@ 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 resetContentAndLayout]; [self resetMappings];
[self updateLastVisibleTimestamp]; [self updateLastVisibleTimestamp];
[self scrollToBottomAnimated:NO]; [self scrollToBottomAnimated:NO];
return; return;
} }
NSUInteger oldViewItemCount = self.viewItems.count; NSUInteger oldViewItemCount = self.viewItems.count;
[self reloadViewItems]; if (![self reloadViewItems]) {
// These errors are rare.
OWSFail(@"%@ could not reload view items; hard resetting message mappings.", self.logTag);
[self resetMappings];
[self updateLastVisibleTimestamp];
[self scrollToBottomAnimated:NO];
return;
}
BOOL wasAtBottom = [self isScrolledToBottom]; BOOL wasAtBottom = [self isScrolledToBottom];
// We want sending messages to feel snappy. So, if the only // We want sending messages to feel snappy. So, if the only
@ -4800,6 +4792,32 @@ typedef enum : NSUInteger {
self.previousLastTimestamp = nil; self.previousLastTimestamp = nil;
} }
- (void)createNewMessageMappings
{
if (self.thread.uniqueId.length > 0) {
self.messageMappings = [[YapDatabaseViewMappings alloc] initWithGroups:@[ self.thread.uniqueId ]
view:TSMessageDatabaseViewExtensionName];
} else {
OWSFail(@"uniqueId unexpectedly empty for thread: %@", self.thread);
self.messageMappings =
[[YapDatabaseViewMappings alloc] initWithGroups:@[] view:TSMessageDatabaseViewExtensionName];
}
// Cells' appearance can depend on adjacent cells in both directions.
[self.messageMappings setCellDrawingDependencyOffsets:[NSSet setWithArray:@[
@(-1),
@(+1),
]]
forGroup:self.thread.uniqueId];
// We need to impose the range restrictions on the mappings immediately to avoid
// doing a great deal of unnecessary work and causing a perf hotspot.
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[self.messageMappings updateWithTransaction:transaction];
}];
[self updateMessageMappingRangeOptions];
}
- (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),
@ -4814,7 +4832,6 @@ typedef enum : NSUInteger {
[self updateMessageMappingRangeOptions]; [self updateMessageMappingRangeOptions];
} }
self.collapseCutoffDate = [NSDate new]; self.collapseCutoffDate = [NSDate new];
[self reloadViewItems];
[self resetContentAndLayout]; [self resetContentAndLayout];
[self ensureDynamicInteractions]; [self ensureDynamicInteractions];
@ -4849,7 +4866,9 @@ typedef enum : NSUInteger {
// This is a key method. It builds or rebuilds the list of // This is a key method. It builds or rebuilds the list of
// cell view models. // cell view models.
- (void)reloadViewItems //
// Returns NO on error.
- (BOOL)reloadViewItems
{ {
NSMutableArray<ConversationViewItem *> *viewItems = [NSMutableArray new]; NSMutableArray<ConversationViewItem *> *viewItems = [NSMutableArray new];
NSMutableDictionary<NSString *, ConversationViewItem *> *viewItemCache = [NSMutableDictionary new]; NSMutableDictionary<NSString *, ConversationViewItem *> *viewItemCache = [NSMutableDictionary new];
@ -4857,6 +4876,7 @@ typedef enum : NSUInteger {
NSUInteger count = [self.messageMappings numberOfItemsInSection:0]; NSUInteger count = [self.messageMappings numberOfItemsInSection:0];
BOOL isGroupThread = self.isGroupConversation; BOOL isGroupThread = self.isGroupConversation;
__block BOOL hasError = NO;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { [self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName]; YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName];
OWSAssert(viewTransaction); OWSAssert(viewTransaction);
@ -4869,6 +4889,7 @@ typedef enum : NSUInteger {
(unsigned long)row, (unsigned long)row,
(unsigned long)count); (unsigned long)count);
// TODO: Add analytics. // TODO: Add analytics.
hasError = YES;
continue; continue;
} }
if (!interaction.uniqueId) { if (!interaction.uniqueId) {
@ -4878,6 +4899,7 @@ typedef enum : NSUInteger {
(unsigned long)count, (unsigned long)count,
interaction); interaction);
// TODO: Add analytics. // TODO: Add analytics.
hasError = YES;
continue; continue;
} }
@ -4894,6 +4916,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;
@ -5122,6 +5152,8 @@ typedef enum : NSUInteger {
self.viewItems = viewItems; self.viewItems = viewItems;
self.viewItemCache = viewItemCache; self.viewItemCache = viewItemCache;
return !hasError;
} }
// Whenever an interaction is modified, we need to reload it from the DB // Whenever an interaction is modified, we need to reload it from the DB

@ -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];

@ -513,7 +513,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
+ (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName + (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName
{ {
DDLogError(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); DDLogError(@"%@ %s %@", self.logTag, __PRETTY_FUNCTION__, extensionName);
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults]; NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
OWSAssert(appUserDefaults); OWSAssert(appUserDefaults);

@ -19,7 +19,7 @@
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>2.29.0</string> <string>2.29.0</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>2.29.0.6</string> <string>2.29.0.9</string>
<key>ITSAppUsesNonExemptEncryption</key> <key>ITSAppUsesNonExemptEncryption</key>
<false/> <false/>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>

Loading…
Cancel
Save