Don't start app version migrations until storage is ready.
This commit is contained in:
parent
2c1e633914
commit
2265ae08aa
|
@ -161,6 +161,11 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
}
|
||||
notificationsProtocolBlock:^{
|
||||
return SignalApp.sharedApp.notificationsManager;
|
||||
}
|
||||
migrationCompletion:^{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
[self versionMigrationsDidComplete];
|
||||
}];
|
||||
|
||||
[UIUtil applySignalAppearence];
|
||||
|
@ -176,14 +181,6 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
mainWindow.rootViewController = [self loadingRootViewController];
|
||||
[mainWindow makeKeyAndVisible];
|
||||
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
[VersionMigrations performUpdateCheckWithCompletion:^{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
[self versionMigrationsDidComplete];
|
||||
}];
|
||||
|
||||
// Accept push notification when app is not open
|
||||
NSDictionary *remoteNotif = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
|
||||
if (remoteNotif) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
@ -14,7 +14,8 @@ typedef id<NotificationsProtocol> _Nonnull (^NotificationsManagerBlock)(void);
|
|||
@interface AppSetup : NSObject
|
||||
|
||||
+ (void)setupEnvironment:(CallMessageHandlerBlock)callMessageHandlerBlock
|
||||
notificationsProtocolBlock:(NotificationsManagerBlock)notificationsManagerBlock;
|
||||
notificationsProtocolBlock:(NotificationsManagerBlock)notificationsManagerBlock
|
||||
migrationCompletion:(dispatch_block_t)migrationCompletion;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -20,9 +20,14 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (void)setupEnvironment:(CallMessageHandlerBlock)callMessageHandlerBlock
|
||||
notificationsProtocolBlock:(NotificationsManagerBlock)notificationsManagerBlock
|
||||
migrationCompletion:(dispatch_block_t)migrationCompletion
|
||||
{
|
||||
OWSAssert(callMessageHandlerBlock);
|
||||
OWSAssert(notificationsManagerBlock);
|
||||
OWSAssert(migrationCompletion);
|
||||
|
||||
__block OWSBackgroundTask *_Nullable backgroundTask =
|
||||
[OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
|
@ -46,7 +51,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[NSKeyedUnarchiver setClass:[OWSUserProfile class] forClassName:[OWSUserProfile collection]];
|
||||
[NSKeyedUnarchiver setClass:[OWSDatabaseMigration class] forClassName:[OWSDatabaseMigration collection]];
|
||||
|
||||
[OWSStorage setupStorage];
|
||||
[OWSStorage setupStorageWithMigrationBlock:^() {
|
||||
// Don't start database migrations until storage is ready.
|
||||
[VersionMigrations performUpdateCheckWithCompletion:^() {
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
migrationCompletion();
|
||||
|
||||
backgroundTask = nil;
|
||||
}];
|
||||
}];
|
||||
[[Environment current].contactsManager startObserving];
|
||||
});
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (void)performUpdateCheckWithCompletion:(VersionMigrationCompletion)completion
|
||||
{
|
||||
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
OWSAssert([Environment current]);
|
||||
|
|
|
@ -58,16 +58,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
OWSAssert(completion);
|
||||
|
||||
OWSDatabaseConnection *dbConnection = (OWSDatabaseConnection *)self.primaryStorage.newDatabaseConnection;
|
||||
// These migrations won't be run until storage registrations are enqueued,
|
||||
// but this transaction might begin before all registrations are marked as
|
||||
// complete, so disable this checking.
|
||||
//
|
||||
// TODO: Once we move "app readiness" into AppSetup, we should explicitly
|
||||
// not start these migrations until storage is ready. We can then remove
|
||||
// this statement which disables checking.
|
||||
#ifdef DEBUG
|
||||
dbConnection.canWriteBeforeStorageReady = YES;
|
||||
#endif
|
||||
|
||||
[dbConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
||||
[self runUpWithTransaction:transaction];
|
||||
|
@ -88,18 +78,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return self.dbReadWriteConnection;
|
||||
}
|
||||
|
||||
// Database migrations need to occur _before_ storage is ready (by definition),
|
||||
// so we need to use a connection with canWriteBeforeStorageReady set in
|
||||
// debug builds.
|
||||
+ (YapDatabaseConnection *)dbReadWriteConnection
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
static YapDatabaseConnection *sharedDBConnection;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedDBConnection = [OWSPrimaryStorage sharedManager].newDatabaseConnection;
|
||||
|
||||
OWSAssert([sharedDBConnection isKindOfClass:[OWSDatabaseConnection class]]);
|
||||
((OWSDatabaseConnection *)sharedDBConnection).canWriteBeforeStorageReady = YES;
|
||||
});
|
||||
|
||||
return sharedDBConnection;
|
||||
|
|
|
@ -22,10 +22,6 @@ extern NSString *const StorageIsReadyNotification;
|
|||
|
||||
@property (atomic, weak) id<OWSDatabaseConnectionDelegate> delegate;
|
||||
|
||||
#ifdef DEBUG
|
||||
@property (atomic) BOOL canWriteBeforeStorageReady;
|
||||
#endif
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initWithDatabase:(YapDatabase *)database
|
||||
delegate:(id<OWSDatabaseConnectionDelegate>)delegate NS_DESIGNATED_INITIALIZER;
|
||||
|
@ -48,6 +44,8 @@ extern NSString *const StorageIsReadyNotification;
|
|||
|
||||
#pragma mark -
|
||||
|
||||
typedef void (^OWSStorageMigrationBlock)(void);
|
||||
|
||||
@interface OWSStorage : NSObject
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
@ -60,7 +58,7 @@ extern NSString *const StorageIsReadyNotification;
|
|||
// This object can be used to filter database notifications.
|
||||
@property (nonatomic, readonly, nullable) id dbNotificationObject;
|
||||
|
||||
+ (void)setupStorage;
|
||||
+ (void)setupStorageWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock;
|
||||
|
||||
+ (void)resetAllStorage;
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
{
|
||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||
OWSAssert(delegate);
|
||||
OWSAssert(delegate.areAllRegistrationsComplete || self.canWriteBeforeStorageReady);
|
||||
OWSAssert(delegate.areAllRegistrationsComplete);
|
||||
|
||||
OWSBackgroundTask *_Nullable backgroundTask = nil;
|
||||
if (CurrentAppContext().isMainApp) {
|
||||
|
@ -101,7 +101,7 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
{
|
||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||
OWSAssert(delegate);
|
||||
OWSAssert(delegate.areAllRegistrationsComplete || self.canWriteBeforeStorageReady);
|
||||
OWSAssert(delegate.areAllRegistrationsComplete);
|
||||
|
||||
__block OWSBackgroundTask *_Nullable backgroundTask = nil;
|
||||
if (CurrentAppContext().isMainApp) {
|
||||
|
@ -176,13 +176,6 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
- (YapDatabaseConnection *)registrationConnection
|
||||
{
|
||||
YapDatabaseConnection *connection = [super registrationConnection];
|
||||
|
||||
#ifdef DEBUG
|
||||
// Flag the registration connection as such.
|
||||
OWSAssert([connection isKindOfClass:[OWSDatabaseConnection class]]);
|
||||
((OWSDatabaseConnection *)connection).canWriteBeforeStorageReady = YES;
|
||||
#endif
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
@ -332,29 +325,24 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
OWS_ABSTRACT_METHOD();
|
||||
}
|
||||
|
||||
+ (NSArray<OWSStorage *> *)allStorages
|
||||
+ (void)setupStorageWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock
|
||||
{
|
||||
return @[
|
||||
OWSPrimaryStorage.sharedManager,
|
||||
];
|
||||
}
|
||||
OWSAssert(migrationBlock);
|
||||
|
||||
+ (void)setupStorage
|
||||
{
|
||||
__block OWSBackgroundTask *_Nullable backgroundTask =
|
||||
[OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
|
||||
|
||||
for (OWSStorage *storage in self.allStorages) {
|
||||
[storage runSyncRegistrations];
|
||||
}
|
||||
[OWSPrimaryStorage.sharedManager runSyncRegistrations];
|
||||
|
||||
for (OWSStorage *storage in self.allStorages) {
|
||||
[storage runAsyncRegistrationsWithCompletion:^{
|
||||
if ([self postRegistrationCompleteNotificationIfPossible]) {
|
||||
backgroundTask = nil;
|
||||
}
|
||||
}];
|
||||
}
|
||||
[OWSPrimaryStorage.sharedManager runAsyncRegistrationsWithCompletion:^{
|
||||
OWSAssert(self.isStorageReady);
|
||||
|
||||
[self postRegistrationCompleteNotification];
|
||||
|
||||
migrationBlock();
|
||||
|
||||
backgroundTask = nil;
|
||||
}];
|
||||
}
|
||||
|
||||
- (YapDatabaseConnection *)registrationConnection
|
||||
|
@ -363,11 +351,11 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
}
|
||||
|
||||
// Returns YES IFF all registrations are complete.
|
||||
+ (BOOL)postRegistrationCompleteNotificationIfPossible
|
||||
+ (void)postRegistrationCompleteNotification
|
||||
{
|
||||
if (!self.isStorageReady) {
|
||||
return NO;
|
||||
}
|
||||
OWSAssert(self.isStorageReady);
|
||||
|
||||
DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__);
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
|
@ -375,18 +363,11 @@ typedef NSData *_Nullable (^CreateDatabaseMetadataBlock)(void);
|
|||
object:nil
|
||||
userInfo:nil];
|
||||
});
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)isStorageReady
|
||||
{
|
||||
for (OWSStorage *storage in self.allStorages) {
|
||||
if (!storage.areAllRegistrationsComplete) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
return OWSPrimaryStorage.sharedManager.areAllRegistrationsComplete;
|
||||
}
|
||||
|
||||
- (BOOL)tryToLoadDatabase
|
||||
|
|
|
@ -90,18 +90,18 @@ public class ShareViewController: UIViewController, ShareViewDelegate, SAEFailed
|
|||
// We shouldn't set up our environment until after we've consulted isReadyForAppExtensions.
|
||||
AppSetup.setupEnvironment({
|
||||
return NoopCallMessageHandler()
|
||||
}) {
|
||||
},
|
||||
notificationsProtocolBlock: {
|
||||
return NoopNotificationsManager()
|
||||
}
|
||||
},
|
||||
migrationCompletion: { [weak self] in
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
VersionMigrations.performUpdateCheck(completion: { [weak self] in
|
||||
SwiftAssertIsOnMainThread(#function)
|
||||
guard let strongSelf = self else { return }
|
||||
|
||||
guard let strongSelf = self else { return }
|
||||
|
||||
strongSelf.versionMigrationsDidComplete()
|
||||
// performUpdateCheck must be invoked after Environment has been initialized because
|
||||
// upgrade process may depend on Environment.
|
||||
strongSelf.versionMigrationsDidComplete()
|
||||
})
|
||||
|
||||
// We don't need to use "screen protection" in the SAE.
|
||||
|
|
Loading…
Reference in New Issue