From 8ba747916a93420a641645ac0719461fb5a6df65 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 11 Dec 2018 14:17:41 -0500 Subject: [PATCH 1/2] Prep orphan data cleaner. --- Signal/src/util/OWSOrphanDataCleaner.m | 67 +++++++++++++++++--------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index e6b9c6e66..78e173653 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -412,17 +412,13 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); return result; } -+ (void)auditOnLaunchIfNecessary -{ ++ (BOOL)shouldAuditOnLaunch:(YapDatabaseConnection *)databaseConnection { OWSAssertIsOnMainThread(); #ifndef ENABLE_ORPHAN_DATA_CLEANER - return; + return NO; #endif - OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; - YapDatabaseConnection *databaseConnection = primaryStorage.dbReadWriteConnection; - __block NSString *_Nullable lastCleaningVersion; __block NSDate *_Nullable lastCleaningDate; [databaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { @@ -432,31 +428,52 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); inCollection:OWSOrphanDataCleaner_Collection]; }]; - // Only clean up once per app version. + // Clean up once per app version. NSString *currentAppVersion = AppVersion.sharedInstance.currentAppVersion; - if (lastCleaningVersion && [lastCleaningVersion isEqualToString:currentAppVersion]) { - OWSLogVerbose(@"skipping orphan data cleanup; already done on %@.", currentAppVersion); - return; + if (!lastCleaningVersion || ![lastCleaningVersion isEqualToString:currentAppVersion]) { + OWSLogVerbose(@"Performing orphan data cleanup; new version: %@.", currentAppVersion); + return YES; + } + + // Clean up once per N days. + if (lastCleaningDate) { +#ifdef DEBUG + BOOL shouldAudit = [DateUtil dateIsOlderThanToday:lastCleaningDate]; +#else + BOOL shouldAudit = [DateUtil dateIsOlderThanOneWeek:lastCleaningDate]; +#endif + + if (shouldAudit) { + OWSLogVerbose(@"Performing orphan data cleanup; time has passed."); + } + return shouldAudit; } - // Only clean up once per day. - if (lastCleaningDate && [DateUtil dateIsToday:lastCleaningDate]) { - OWSLogVerbose(@"skipping orphan data cleanup; already done today."); + // Has never audited before. + return NO; +} + ++ (void)auditOnLaunchIfNecessary { + OWSAssertIsOnMainThread(); + + OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; + YapDatabaseConnection *databaseConnection = primaryStorage.dbReadWriteConnection; + + if (![self shouldAuditOnLaunch:databaseConnection]) { return; } // If we want to be cautious, we can disable orphan deletion using // flag - the cleanup will just be a dry run with logging. - BOOL shouldRemoveOrphans = NO; + BOOL shouldRemoveOrphans = YES; [self auditAndCleanup:shouldRemoveOrphans databaseConnection:databaseConnection completion:nil]; } + (void)auditAndCleanup:(BOOL)shouldRemoveOrphans { - OWSPrimaryStorage *primaryStorage = [OWSPrimaryStorage sharedManager]; - YapDatabaseConnection *databaseConnection = primaryStorage.dbReadWriteConnection; - - [self auditAndCleanup:shouldRemoveOrphans databaseConnection:databaseConnection completion:nil]; + [self auditAndCleanup:shouldRemoveOrphans + completion:^ { + }]; } + (void)auditAndCleanup:(BOOL)shouldRemoveOrphans completion:(dispatch_block_t)completion @@ -480,6 +497,8 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSAssertIsOnMainThread(); OWSAssertDebug(databaseConnection); + OWSLogVerbose(@""); + if (!AppReadiness.isAppReady) { OWSFailDebug(@"can't audit orphan data until app is ready."); return; @@ -569,6 +588,8 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSAssertDebug(databaseConnection); OWSAssertDebug(orphanData); + OWSLogVerbose(@""); + if (remainingRetries < 1) { OWSLogInfo(@"Aborting orphan data audit."); dispatch_async(self.workQueue, ^{ @@ -608,9 +629,11 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSAssertDebug(databaseConnection); OWSAssertDebug(orphanData); + OWSLogVerbose(@""); + __block BOOL shouldAbort = NO; - // We need to avoid cleaning up new attachments and files that are still in the process of + // We need to avoid cleaning up new files that are still in the process of // being created/written, so we don't clean up anything recent. const NSTimeInterval kMinimumOrphanAgeSeconds = CurrentAppContext().isRunningTests ? 0.f : 15 * kMinuteInterval; NSDate *appLaunchTime = CurrentAppContext().appLaunchTime; @@ -700,10 +723,10 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); // Don't delete files which were created in the last N minutes. NSDate *creationDate = attributes.fileModificationDate; if ([creationDate isAfterDate:thresholdDate]) { - OWSLogInfo(@"Skipping orphan attachment file due to age: %f", fabs([creationDate timeIntervalSinceNow])); + OWSLogInfo(@"Skipping file due to age: %f", fabs([creationDate timeIntervalSinceNow])); continue; } - OWSLogInfo(@"Deleting orphan attachment file: %@", filePath); + OWSLogInfo(@"Deleting file: %@", filePath); filesRemoved++; if (!shouldRemoveOrphans) { continue; @@ -714,7 +737,7 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSFailDebug(@"Could not remove orphan file"); } } - OWSLogInfo(@"Deleted orphan attachment files: %zu", filesRemoved); + OWSLogInfo(@"Deleted orphan files: %zu", filesRemoved); return YES; } From af3cff3399985ef20217d7b33740e2756146d2b9 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 11 Dec 2018 14:20:01 -0500 Subject: [PATCH 2/2] Prep orphan data cleaner. --- Signal/src/util/OWSOrphanDataCleaner.m | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Signal/src/util/OWSOrphanDataCleaner.m b/Signal/src/util/OWSOrphanDataCleaner.m index 78e173653..14a06611a 100644 --- a/Signal/src/util/OWSOrphanDataCleaner.m +++ b/Signal/src/util/OWSOrphanDataCleaner.m @@ -497,8 +497,6 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSAssertIsOnMainThread(); OWSAssertDebug(databaseConnection); - OWSLogVerbose(@""); - if (!AppReadiness.isAppReady) { OWSFailDebug(@"can't audit orphan data until app is ready."); return; @@ -588,8 +586,6 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSAssertDebug(databaseConnection); OWSAssertDebug(orphanData); - OWSLogVerbose(@""); - if (remainingRetries < 1) { OWSLogInfo(@"Aborting orphan data audit."); dispatch_async(self.workQueue, ^{ @@ -629,8 +625,6 @@ typedef void (^OrphanDataBlock)(OWSOrphanData *); OWSAssertDebug(databaseConnection); OWSAssertDebug(orphanData); - OWSLogVerbose(@""); - __block BOOL shouldAbort = NO; // We need to avoid cleaning up new files that are still in the process of