Merge branch 'charlesmchen/debugUIRefinements_'

pull/1/head
Matthew Chen 7 years ago
commit f4323411d2

@ -108,10 +108,16 @@
- (void)updateTableContents - (void)updateTableContents
{ {
OWSTableContents *contents = [OWSTableContents new]; OWSTableContents *contents = [OWSTableContents new];
OWSTableSection *section = [OWSTableSection new];
__weak AppSettingsViewController *weakSelf = self; __weak AppSettingsViewController *weakSelf = self;
#ifdef INTERNAL
OWSTableSection *internalSection = [OWSTableSection new];
[section addItem:[OWSTableItem softCenterLabelItemWithText:@"Internal Build"]];
[contents addSection:internalSection];
#endif
OWSTableSection *section = [OWSTableSection new];
[section addItem:[OWSTableItem itemWithCustomCellBlock:^{ [section addItem:[OWSTableItem itemWithCustomCellBlock:^{
return [weakSelf profileHeaderCell]; return [weakSelf profileHeaderCell];
} }

@ -2834,23 +2834,26 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
// We need to reload any modified interactions _before_ we call // We need to reload any modified interactions _before_ we call
// reloadViewItems. // reloadViewItems.
BOOL hasDeletions = NO; BOOL hasDeletions = NO;
BOOL hasMalformedRowChange = NO;
for (YapDatabaseViewRowChange *rowChange in rowChanges) { for (YapDatabaseViewRowChange *rowChange in rowChanges) {
switch (rowChange.type) { switch (rowChange.type) {
case YapDatabaseViewChangeUpdate: { case YapDatabaseViewChangeUpdate: {
YapCollectionKey *collectionKey = rowChange.collectionKey; YapCollectionKey *collectionKey = rowChange.collectionKey;
OWSAssert(collectionKey.key.length > 0);
if (collectionKey.key) { if (collectionKey.key) {
ConversationViewItem *viewItem = self.viewItemCache[collectionKey.key]; ConversationViewItem *viewItem = self.viewItemCache[collectionKey.key];
[self reloadInteractionForViewItem:viewItem]; [self reloadInteractionForViewItem:viewItem];
} else {
hasMalformedRowChange = YES;
} }
break; break;
} }
case YapDatabaseViewChangeDelete: { case YapDatabaseViewChangeDelete: {
// Discard cached view items after deletes. // Discard cached view items after deletes.
YapCollectionKey *collectionKey = rowChange.collectionKey; YapCollectionKey *collectionKey = rowChange.collectionKey;
OWSAssert(collectionKey.key.length > 0);
if (collectionKey.key) { if (collectionKey.key) {
[self.viewItemCache removeObjectForKey:collectionKey.key]; [self.viewItemCache removeObjectForKey:collectionKey.key];
} else {
hasMalformedRowChange = YES;
} }
hasDeletions = YES; hasDeletions = YES;
break; break;
@ -2858,6 +2861,19 @@ typedef NS_ENUM(NSInteger, MessagesRangeSizeMode) {
default: default:
break; break;
} }
if (hasMalformedRowChange) {
break;
}
}
if (hasMalformedRowChange) {
// These errors seems to be very rare; they can only be reproduced
// using the more extreme actions in the debug UI.
DDLogError(@"%@ hasMalformedRowChange", self.logTag);
[self.collectionView reloadData];
[self updateLastVisibleTimestamp];
[self cleanUpUnreadIndicatorIfNecessary];
return;
} }
NSUInteger oldViewItemCount = self.viewItems.count; NSUInteger oldViewItemCount = self.viewItems.count;

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "DebugUIMessages.h" #import "DebugUIMessages.h"
@ -124,6 +124,14 @@ NS_ASSUME_NONNULL_BEGIN
actionBlock:^{ actionBlock:^{
[DebugUIMessages sendFakeMessages:10 * 1000 thread:thread]; [DebugUIMessages sendFakeMessages:10 * 1000 thread:thread];
}], }],
[OWSTableItem itemWithTitle:@"Create 100k fake messages"
actionBlock:^{
[DebugUIMessages sendFakeMessages:100 * 1000 thread:thread];
}],
[OWSTableItem itemWithTitle:@"Create 100k fake text messages"
actionBlock:^{
[DebugUIMessages sendFakeMessages:100 * 1000 thread:thread isTextOnly:YES];
}],
[OWSTableItem itemWithTitle:@"Create 1 fake unread messages" [OWSTableItem itemWithTitle:@"Create 1 fake unread messages"
actionBlock:^{ actionBlock:^{
[DebugUIMessages createFakeUnreadMessages:1 thread:thread]; [DebugUIMessages createFakeUnreadMessages:1 thread:thread];
@ -282,9 +290,24 @@ NS_ASSUME_NONNULL_BEGIN
[DebugUIMessages createNewGroups:1000 recipientId:recipientId]; [DebugUIMessages createNewGroups:1000 recipientId:recipientId];
}]]; }]];
} }
if ([thread isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *groupThread = (TSGroupThread *)thread;
[items addObject:[OWSTableItem itemWithTitle:@"Send message to all members"
actionBlock:^{
[DebugUIMessages sendMessages:1 toAllMembersOfGroup:groupThread];
}]];
}
return [OWSTableSection sectionWithTitle:self.name items:items]; return [OWSTableSection sectionWithTitle:self.name items:items];
} }
+ (void)sendMessages:(int)counter toAllMembersOfGroup:(TSGroupThread *)groupThread
{
for (NSString *recipientId in groupThread.groupModel.groupMemberIds) {
TSContactThread *contactThread = [TSContactThread getOrCreateThreadWithContactId:recipientId];
[DebugUIMessages sendTextMessages:counter thread:contactThread];
}
}
+ (void)sendTextMessageInThread:(TSThread *)thread counter:(int)counter + (void)sendTextMessageInThread:(TSThread *)thread counter:(int)counter
{ {
DDLogInfo(@"%@ sendTextMessageInThread: %d", self.logTag, counter); DDLogInfo(@"%@ sendTextMessageInThread: %d", self.logTag, counter);
@ -964,20 +987,42 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)sendFakeMessages:(NSUInteger)counter thread:(TSThread *)thread + (void)sendFakeMessages:(NSUInteger)counter thread:(TSThread *)thread
{ {
[self sendFakeMessages:counter thread:thread isTextOnly:NO];
}
+ (void)sendFakeMessages:(NSUInteger)counter thread:(TSThread *)thread isTextOnly:(BOOL)isTextOnly
{
const NSUInteger kMaxBatchSize = 2500;
if (counter < kMaxBatchSize) {
[TSStorageManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [TSStorageManager.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self sendFakeMessages:counter thread:thread transaction:transaction]; [self sendFakeMessages:counter thread:thread isTextOnly:isTextOnly transaction:transaction];
}]; }];
} else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSUInteger remainder = counter;
while (remainder > 0) {
NSUInteger batchSize = MIN(kMaxBatchSize, remainder);
[TSStorageManager.dbReadWriteConnection
readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self sendFakeMessages:batchSize thread:thread isTextOnly:isTextOnly transaction:transaction];
}];
remainder -= batchSize;
DDLogInfo(@"%@ sendFakeMessages %zd / %zd", self.logTag, counter - remainder, counter);
}
});
}
} }
+ (void)sendFakeMessages:(NSUInteger)counter + (void)sendFakeMessages:(NSUInteger)counter
thread:(TSThread *)thread thread:(TSThread *)thread
isTextOnly:(BOOL)isTextOnly
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
DDLogInfo(@"%@ sendFakeMessages: %zd", self.logTag, counter); DDLogInfo(@"%@ sendFakeMessages: %zd", self.logTag, counter);
for (NSUInteger i = 0; i < counter; i++) { for (NSUInteger i = 0; i < counter; i++) {
NSString *randomText = [self randomText]; NSString *randomText = [self randomText];
switch (arc4random_uniform(4)) { switch (arc4random_uniform(isTextOnly ? 2 : 4)) {
case 0: { case 0: {
TSIncomingMessage *message = TSIncomingMessage *message =
[[TSIncomingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] [[TSIncomingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
@ -985,7 +1030,6 @@ NS_ASSUME_NONNULL_BEGIN
authorId:@"+19174054215" authorId:@"+19174054215"
sourceDeviceId:0 sourceDeviceId:0
messageBody:randomText]; messageBody:randomText];
DDLogError(@"%@ sendFakeMessages incoming timestamp: %llu.", self.logTag, message.timestamp);
[message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO];
break; break;
} }
@ -994,8 +1038,8 @@ NS_ASSUME_NONNULL_BEGIN
[[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread inThread:thread
messageBody:randomText]; messageBody:randomText];
DDLogError(@"%@ sendFakeMessages outgoing timestamp: %llu.", self.logTag, message.timestamp);
[message saveWithTransaction:transaction]; [message saveWithTransaction:transaction];
[message updateWithMessageState:TSOutgoingMessageStateUnsent transaction:transaction];
break; break;
} }
case 2: { case 2: {
@ -1009,6 +1053,7 @@ NS_ASSUME_NONNULL_BEGIN
relay:@"" relay:@""
sourceFilename:@"test.mp3" sourceFilename:@"test.mp3"
attachmentType:TSAttachmentTypeDefault]; attachmentType:TSAttachmentTypeDefault];
pointer.state = TSAttachmentPointerStateFailed;
[pointer saveWithTransaction:transaction]; [pointer saveWithTransaction:transaction];
TSIncomingMessage *message = TSIncomingMessage *message =
[[TSIncomingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] [[TSIncomingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
@ -1020,7 +1065,6 @@ NS_ASSUME_NONNULL_BEGIN
pointer.uniqueId, pointer.uniqueId,
] ]
expiresInSeconds:0]; expiresInSeconds:0];
DDLogError(@"%@ sendFakeMessages incoming attachment timestamp: %llu.", self.logTag, message.timestamp);
[message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO]; [message markAsReadWithTransaction:transaction sendReadReceipt:NO updateExpiration:NO];
break; break;
} }
@ -1031,7 +1075,6 @@ NS_ASSUME_NONNULL_BEGIN
messageBody:nil messageBody:nil
isVoiceMessage:NO isVoiceMessage:NO
expiresInSeconds:0]; expiresInSeconds:0];
DDLogError(@"%@ sendFakeMessages outgoing attachment timestamp: %llu.", self.logTag, message.timestamp);
NSString *filename = @"test.mp3"; NSString *filename = @"test.mp3";
UInt32 filesize = 16; UInt32 filesize = 16;
@ -1050,6 +1093,7 @@ NS_ASSUME_NONNULL_BEGIN
message.attachmentFilenameMap[attachmentStream.uniqueId] = filename; message.attachmentFilenameMap[attachmentStream.uniqueId] = filename;
} }
[message saveWithTransaction:transaction]; [message saveWithTransaction:transaction];
[message updateWithMessageState:TSOutgoingMessageStateUnsent transaction:transaction];
break; break;
} }
} }
@ -1248,7 +1292,7 @@ NS_ASSUME_NONNULL_BEGIN
}, },
^(YapDatabaseReadWriteTransaction *transaction) { ^(YapDatabaseReadWriteTransaction *transaction) {
NSUInteger messageCount = (NSUInteger)(1 + arc4random_uniform(4)); NSUInteger messageCount = (NSUInteger)(1 + arc4random_uniform(4));
[self sendFakeMessages:messageCount thread:thread transaction:transaction]; [self sendFakeMessages:messageCount thread:thread isTextOnly:NO transaction:transaction];
}, },
^(YapDatabaseReadWriteTransaction *transaction) { ^(YapDatabaseReadWriteTransaction *transaction) {
NSUInteger messageCount = (NSUInteger)(1 + arc4random_uniform(4)); NSUInteger messageCount = (NSUInteger)(1 + arc4random_uniform(4));

@ -141,6 +141,10 @@ void runAsyncRegistrationsForStorage(OWSStorage *storage)
+ (void)protectFiles + (void)protectFiles
{ {
DDLogInfo(@"%@ Database file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.legacyDatabaseFilePath]);
DDLogInfo(@"%@ \t SHM file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.legacyDatabaseFilePath_SHM]);
DDLogInfo(@"%@ \t WAL file size: %@", self.logTag, [OWSFileSystem fileSizeOfPath:self.legacyDatabaseFilePath_WAL]);
// The old database location was in the Document directory, // The old database location was in the Document directory,
// so protect the database files individually. // so protect the database files individually.
[OWSFileSystem protectFileOrFolderAtPath:self.legacyDatabaseFilePath]; [OWSFileSystem protectFileOrFolderAtPath:self.legacyDatabaseFilePath];

@ -35,6 +35,8 @@ NS_ASSUME_NONNULL_BEGIN
// Returns nil on failure. // Returns nil on failure.
+ (nullable NSString *)writeDataToTemporaryFile:(NSData *)data fileExtension:(NSString *_Nullable)fileExtension; + (nullable NSString *)writeDataToTemporaryFile:(NSData *)data fileExtension:(NSString *_Nullable)fileExtension;
+ (nullable NSNumber *)fileSizeOfPath:(NSString *)filePath;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

@ -200,6 +200,20 @@ NS_ASSUME_NONNULL_BEGIN
return tempFilePath; return tempFilePath;
} }
+ (nullable NSNumber *)fileSizeOfPath:(NSString *)filePath
{
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *_Nullable error;
unsigned long long fileSize =
[[fileManager attributesOfItemAtPath:filePath error:&error][NSFileSize] unsignedLongLongValue];
if (error) {
DDLogError(@"%@ Couldn't fetch file size[%@]: %@", self.logTag, filePath, error);
return nil;
} else {
return @(fileSize);
}
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

Loading…
Cancel
Save