mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Rework database view registration.
This commit is contained in:
parent
f88b954ab5
commit
fe67cd924c
12 changed files with 156 additions and 147 deletions
|
@ -135,7 +135,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
// Prevent the device from sleeping during database view async registration
|
||||
// (e.g. long database upgrades).
|
||||
//
|
||||
// This block will be cleared in databaseViewRegistrationComplete.
|
||||
// This block will be cleared in storageIsReady.
|
||||
[DeviceSleepManager.sharedInstance addBlockWithBlockObject:self];
|
||||
|
||||
[AppSetup setupEnvironment:^{
|
||||
|
@ -175,8 +175,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
[OWSContactsSyncing sharedManager];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(databaseViewRegistrationComplete)
|
||||
name:DatabaseViewRegistrationCompleteNotification
|
||||
selector:@selector(storageIsReady)
|
||||
name:StorageIsReadyNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(registrationStateDidChange)
|
||||
|
@ -713,9 +713,9 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)databaseViewRegistrationComplete
|
||||
- (void)storageIsReady
|
||||
{
|
||||
DDLogInfo(@"%@ databaseViewRegistrationComplete", self.logTag);
|
||||
DDLogInfo(@"%@ storageIsReady", self.logTag);
|
||||
|
||||
[OWSPreferences setIsRegistered:[TSAccountManager isRegistered]];
|
||||
|
||||
|
@ -739,8 +739,6 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
|
||||
[Environment.current.contactsManager loadSignalAccountsFromCache];
|
||||
|
||||
[self ensureRootViewController];
|
||||
|
||||
// If there were any messages in our local queue which we hadn't yet processed.
|
||||
[[OWSMessageReceiver sharedInstance] handleAnyUnprocessedEnvelopesAsync];
|
||||
[[OWSBatchMessageProcessor sharedInstance] handleAnyUnprocessedEnvelopesAsync];
|
||||
|
@ -766,6 +764,8 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
// Disable the SAE until the main app has successfully completed launch process
|
||||
// at least once in the post-SAE world.
|
||||
[OWSPreferences setIsReadyForAppExtensions];
|
||||
|
||||
[self ensureRootViewController];
|
||||
}
|
||||
|
||||
- (void)registrationStateDidChange
|
||||
|
@ -797,7 +797,7 @@ static NSString *const kURLHostVerifyPrefix = @"verify";
|
|||
{
|
||||
DDLogInfo(@"%@ ensureRootViewController", self.logTag);
|
||||
|
||||
if ([TSDatabaseView hasPendingViewRegistrations] || self.hasInitialRootViewController) {
|
||||
if (![OWSStorage isStorageReady] || self.hasInitialRootViewController) {
|
||||
return;
|
||||
}
|
||||
self.hasInitialRootViewController = YES;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#import <AxolotlKit/SessionCipher.h>
|
||||
#import <SignalMessaging/OWSProfileManager.h>
|
||||
#import <SignalMessaging/SignalMessaging-Swift.h>
|
||||
#import <SignalServiceKit/OWSStorage.h>
|
||||
#import <SignalServiceKit/TextSecureKitEnv.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
@ -39,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
profileManager:OWSProfileManager.sharedManager];
|
||||
[TextSecureKitEnv setSharedEnv:sharedEnv];
|
||||
|
||||
[[TSStorageManager sharedManager] setupDatabaseWithSafeBlockingMigrations:^{
|
||||
[OWSStorage setupWithSafeBlockingMigrations:^{
|
||||
[VersionMigrations runSafeBlockingMigrations];
|
||||
}];
|
||||
[[Environment current].contactsManager startObserving];
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#import "OWSMessageManager.h"
|
||||
#import "OWSQueues.h"
|
||||
#import "OWSSignalServiceProtos.pb.h"
|
||||
#import "OWSStorage.h"
|
||||
#import "TSDatabaseView.h"
|
||||
#import "TSStorageManager.h"
|
||||
#import "TSYapDatabaseObject.h"
|
||||
|
@ -261,8 +262,8 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
|
|||
_isDrainingQueue = NO;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(databaseViewRegistrationComplete)
|
||||
name:DatabaseViewRegistrationCompleteNotification
|
||||
selector:@selector(storageIsReady)
|
||||
name:StorageIsReadyNotification
|
||||
object:nil];
|
||||
|
||||
return self;
|
||||
|
@ -273,7 +274,7 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
|
|||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)databaseViewRegistrationComplete
|
||||
- (void)storageIsReady
|
||||
{
|
||||
[self drainQueue];
|
||||
}
|
||||
|
@ -306,9 +307,8 @@ NSString *const OWSMessageContentJobFinderExtensionGroup = @"OWSMessageContentJo
|
|||
}
|
||||
|
||||
dispatch_async(self.serialQueue, ^{
|
||||
if ([TSDatabaseView hasPendingViewRegistrations]) {
|
||||
// We don't want to process incoming messages until database
|
||||
// view registration is complete.
|
||||
if (![OWSStorage isStorageReady]) {
|
||||
// We don't want to process incoming messages until storage is ready.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#import "OWSMessageDecrypter.h"
|
||||
#import "OWSQueues.h"
|
||||
#import "OWSSignalServiceProtos.pb.h"
|
||||
#import "OWSStorage.h"
|
||||
#import "TSDatabaseView.h"
|
||||
#import "TSStorageManager.h"
|
||||
#import "TSYapDatabaseObject.h"
|
||||
|
@ -241,8 +242,8 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
|
|||
_isDrainingQueue = NO;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(databaseViewRegistrationComplete)
|
||||
name:DatabaseViewRegistrationCompleteNotification
|
||||
selector:@selector(storageIsReady)
|
||||
name:StorageIsReadyNotification
|
||||
object:nil];
|
||||
|
||||
return self;
|
||||
|
@ -253,7 +254,7 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
|
|||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)databaseViewRegistrationComplete
|
||||
- (void)storageIsReady
|
||||
{
|
||||
[self drainQueue];
|
||||
}
|
||||
|
@ -283,9 +284,8 @@ NSString *const OWSMessageDecryptJobFinderExtensionGroup = @"OWSMessageProcessin
|
|||
}
|
||||
|
||||
dispatch_async(self.serialQueue, ^{
|
||||
if ([TSDatabaseView hasPendingViewRegistrations]) {
|
||||
// We don't want to process incoming messages until database
|
||||
// view registration is complete.
|
||||
if (![OWSStorage isStorageReady]) {
|
||||
// We don't want to process incoming messages until storage is ready.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#import "OWSReadReceiptsForLinkedDevicesMessage.h"
|
||||
#import "OWSReadReceiptsForSenderMessage.h"
|
||||
#import "OWSSignalServiceProtos.pb.h"
|
||||
#import "OWSStorage.h"
|
||||
#import "OWSSyncConfigurationMessage.h"
|
||||
#import "TSContactThread.h"
|
||||
#import "TSDatabaseView.h"
|
||||
|
@ -176,8 +177,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
|||
OWSSingletonAssert();
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(databaseViewRegistrationComplete)
|
||||
name:DatabaseViewRegistrationCompleteNotification
|
||||
selector:@selector(storageIsReady)
|
||||
name:StorageIsReadyNotification
|
||||
object:nil];
|
||||
|
||||
// Try to start processing.
|
||||
|
@ -191,7 +192,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
|||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)databaseViewRegistrationComplete
|
||||
- (void)storageIsReady
|
||||
{
|
||||
[self scheduleProcessing];
|
||||
}
|
||||
|
@ -202,9 +203,8 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
|||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||
@synchronized(self)
|
||||
{
|
||||
if ([TSDatabaseView hasPendingViewRegistrations]) {
|
||||
DDLogInfo(
|
||||
@"%@ Deferring read receipt processing due to pending database view registrations.", self.logTag);
|
||||
if (![OWSStorage isStorageReady]) {
|
||||
DDLogInfo(@"%@ Deferring read receipt processing; storage not yet ready.", self.logTag);
|
||||
return;
|
||||
}
|
||||
if (self.isProcessing) {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern NSString *const StorageIsReadyNotification;
|
||||
|
||||
@class YapDatabaseExtension;
|
||||
|
||||
@interface OWSStorage : NSObject
|
||||
|
@ -13,7 +15,23 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
- (instancetype)init NS_UNAVAILABLE;
|
||||
- (instancetype)initStorage NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (void)setSyncRegistrationsAreComplete;
|
||||
+ (BOOL)isStorageReady;
|
||||
|
||||
- (void)runSyncRegistrations;
|
||||
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion;
|
||||
|
||||
- (BOOL)areAsyncRegistrationsComplete;
|
||||
- (BOOL)areSyncRegistrationsComplete;
|
||||
|
||||
/**
|
||||
* The safeBlockingMigrationsBlock block will
|
||||
* run any outstanding version migrations that are a) blocking and b) safe
|
||||
* to be run before the environment and storage is completely configured.
|
||||
*
|
||||
* Specifically, these migration should not depend on or affect the data
|
||||
* of any database view.
|
||||
*/
|
||||
+ (void)setupWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock;
|
||||
|
||||
+ (void)resetAllStorage;
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#import "OWSStorage.h"
|
||||
#import "AppContext.h"
|
||||
#import "NSData+Base64.h"
|
||||
#import "NSNotificationCenter+OWS.h"
|
||||
#import "TSAttachmentStream.h"
|
||||
#import "TSStorageManager.h"
|
||||
#import <Curve25519Kit/Randomness.h>
|
||||
|
@ -13,6 +14,8 @@
|
|||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
NSString *const StorageIsReadyNotification = @"StorageIsReadyNotification";
|
||||
|
||||
NSString *const OWSStorageExceptionName_DatabasePasswordInaccessibleWhileBackgrounded
|
||||
= @"OWSStorageExceptionName_DatabasePasswordInaccessibleWhileBackgrounded";
|
||||
NSString *const OWSStorageExceptionName_DatabasePasswordUnwritable
|
||||
|
@ -26,7 +29,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
|
||||
@protocol OWSDatabaseConnectionDelegate <NSObject>
|
||||
|
||||
- (BOOL)areSyncRegistrationsAreComplete;
|
||||
- (BOOL)areSyncRegistrationsComplete;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -80,7 +83,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
{
|
||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||
OWSAssert(delegate);
|
||||
OWSAssert(delegate.areSyncRegistrationsAreComplete);
|
||||
OWSAssert(delegate.areSyncRegistrationsComplete);
|
||||
|
||||
[super readWriteWithBlock:block];
|
||||
}
|
||||
|
@ -89,7 +92,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
{
|
||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||
OWSAssert(delegate);
|
||||
OWSAssert(delegate.areSyncRegistrationsAreComplete);
|
||||
OWSAssert(delegate.areSyncRegistrationsComplete);
|
||||
|
||||
[super asyncReadWriteWithBlock:block];
|
||||
}
|
||||
|
@ -99,7 +102,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
{
|
||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||
OWSAssert(delegate);
|
||||
OWSAssert(delegate.areSyncRegistrationsAreComplete);
|
||||
OWSAssert(delegate.areSyncRegistrationsComplete);
|
||||
|
||||
[super asyncReadWriteWithBlock:block completionBlock:completionBlock];
|
||||
}
|
||||
|
@ -110,7 +113,7 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
{
|
||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||
OWSAssert(delegate);
|
||||
OWSAssert(delegate.areSyncRegistrationsAreComplete);
|
||||
OWSAssert(delegate.areSyncRegistrationsComplete);
|
||||
|
||||
[super asyncReadWriteWithBlock:block completionQueue:completionQueue completionBlock:completionBlock];
|
||||
}
|
||||
|
@ -232,7 +235,6 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
@interface OWSStorage () <OWSDatabaseConnectionDelegate>
|
||||
|
||||
@property (atomic, nullable) YapDatabase *database;
|
||||
@property (atomic) BOOL areSyncRegistrationsAreComplete;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -270,11 +272,82 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void)setSyncRegistrationsAreComplete
|
||||
- (BOOL)areAsyncRegistrationsComplete
|
||||
{
|
||||
OWSAssert(!self.areSyncRegistrationsAreComplete);
|
||||
OWS_ABSTRACT_METHOD();
|
||||
|
||||
self.areSyncRegistrationsAreComplete = YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)areSyncRegistrationsComplete
|
||||
{
|
||||
OWS_ABSTRACT_METHOD();
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)runSyncRegistrations
|
||||
{
|
||||
OWS_ABSTRACT_METHOD();
|
||||
}
|
||||
|
||||
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion
|
||||
{
|
||||
OWS_ABSTRACT_METHOD();
|
||||
}
|
||||
|
||||
+ (NSArray<OWSStorage *> *)allStorages
|
||||
{
|
||||
return @[
|
||||
TSStorageManager.sharedManager,
|
||||
];
|
||||
}
|
||||
|
||||
+ (void)setupWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock
|
||||
{
|
||||
OWSAssert(safeBlockingMigrationsBlock);
|
||||
|
||||
for (OWSStorage *storage in self.allStorages) {
|
||||
[storage runSyncRegistrations];
|
||||
}
|
||||
|
||||
// Run the blocking migrations.
|
||||
//
|
||||
// These need to run _before_ the async registered database views or
|
||||
// they will block on them, which (in the upgrade case) can block
|
||||
// return of appDidFinishLaunching... which in term can cause the
|
||||
// app to crash on launch.
|
||||
safeBlockingMigrationsBlock();
|
||||
|
||||
for (OWSStorage *storage in self.allStorages) {
|
||||
[storage runAsyncRegistrationsWithCompletion:^{
|
||||
[self postRegistrationCompleteNotificationIfPossible];
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)postRegistrationCompleteNotificationIfPossible
|
||||
{
|
||||
if (!self.isStorageReady) {
|
||||
return;
|
||||
}
|
||||
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:StorageIsReadyNotification
|
||||
object:nil
|
||||
userInfo:nil];
|
||||
});
|
||||
}
|
||||
|
||||
+ (BOOL)isStorageReady
|
||||
{
|
||||
for (OWSStorage *storage in self.allStorages) {
|
||||
if (!storage.areAsyncRegistrationsComplete) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)tryToLoadDatabase
|
||||
|
@ -373,7 +446,9 @@ static NSString *keychainDBPassAccount = @"TSDatabasePass";
|
|||
|
||||
+ (void)resetAllStorage
|
||||
{
|
||||
[[TSStorageManager sharedManager] resetStorage];
|
||||
for (OWSStorage *storage in self.allStorages) {
|
||||
[storage resetStorage];
|
||||
}
|
||||
|
||||
[self deletePasswordFromKeychain];
|
||||
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
|
||||
#import <YapDatabase/YapDatabaseViewTransaction.h>
|
||||
|
||||
extern NSString *const DatabaseViewRegistrationCompleteNotification;
|
||||
|
||||
extern NSString *const TSInboxGroup;
|
||||
extern NSString *const TSArchiveGroup;
|
||||
extern NSString *const TSUnreadIncomingMessagesGroup;
|
||||
|
@ -22,9 +20,6 @@ extern NSString *const TSSecondaryDevicesDatabaseViewExtensionName;
|
|||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
// This method can be called from any thread.
|
||||
+ (BOOL)hasPendingViewRegistrations;
|
||||
|
||||
+ (void)registerCrossProcessNotifier;
|
||||
|
||||
// This method must be called _AFTER_ registerThreadInteractionsDatabaseView.
|
||||
|
@ -57,7 +52,4 @@ extern NSString *const TSSecondaryDevicesDatabaseViewExtensionName;
|
|||
// NOTE: It is not safe to call this method while hasPendingViewRegistrations is YES.
|
||||
+ (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction;
|
||||
|
||||
// This method should be called _after_ all async database registrations have been started.
|
||||
+ (void)asyncRegistrationCompletion;
|
||||
|
||||
@end
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
//
|
||||
|
||||
#import "TSDatabaseView.h"
|
||||
#import "NSNotificationCenter+OWS.h"
|
||||
#import "OWSDevice.h"
|
||||
#import "OWSReadTracking.h"
|
||||
#import "TSIncomingMessage.h"
|
||||
|
@ -15,8 +14,6 @@
|
|||
#import <YapDatabase/YapDatabaseCrossProcessNotification.h>
|
||||
#import <YapDatabase/YapDatabaseViewTypes.h>
|
||||
|
||||
NSString *const DatabaseViewRegistrationCompleteNotification = @"DatabaseViewRegistrationCompleteNotification";
|
||||
|
||||
NSString *const TSInboxGroup = @"TSInboxGroup";
|
||||
NSString *const TSArchiveGroup = @"TSArchiveGroup";
|
||||
|
||||
|
@ -33,62 +30,8 @@ NSString *const TSUnseenDatabaseViewExtensionName = @"TSUnseenDatabaseViewExtens
|
|||
NSString *const TSThreadSpecialMessagesDatabaseViewExtensionName = @"TSThreadSpecialMessagesDatabaseViewExtensionName";
|
||||
NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevicesDatabaseViewExtensionName";
|
||||
|
||||
@interface TSDatabaseView ()
|
||||
|
||||
@property (nonatomic) BOOL areAllAsyncRegistrationsComplete;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation TSDatabaseView
|
||||
|
||||
+ (instancetype)sharedInstance
|
||||
{
|
||||
static TSDatabaseView *sharedInstance = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] initDefault];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (instancetype)initDefault
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
OWSSingletonAssert();
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)hasPendingViewRegistrations
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
return !self.areAllAsyncRegistrationsComplete;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)hasPendingViewRegistrations
|
||||
{
|
||||
return ![TSDatabaseView sharedInstance].areAllAsyncRegistrationsComplete;
|
||||
}
|
||||
|
||||
- (void)setAreAllAsyncRegistrationsComplete
|
||||
{
|
||||
@synchronized(self)
|
||||
{
|
||||
OWSAssert(!self.areAllAsyncRegistrationsComplete);
|
||||
|
||||
self.areAllAsyncRegistrationsComplete = YES;
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)registerCrossProcessNotifier
|
||||
{
|
||||
// I don't think the identifier and name of this extension matter for our purposes,
|
||||
|
@ -444,19 +387,4 @@ NSString *const TSSecondaryDevicesDatabaseViewExtensionName = @"TSSecondaryDevic
|
|||
return result;
|
||||
}
|
||||
|
||||
+ (void)asyncRegistrationCompletion
|
||||
{
|
||||
OWSAssertIsOnMainThread();
|
||||
|
||||
// All async registrations are complete when writes are unblocked.
|
||||
[[TSStorageManager sharedManager].newDatabaseConnection
|
||||
asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
||||
[TSDatabaseView.sharedInstance setAreAllAsyncRegistrationsComplete];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:DatabaseViewRegistrationCompleteNotification
|
||||
object:nil
|
||||
userInfo:nil];
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -12,16 +12,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (instancetype)sharedManager;
|
||||
|
||||
/**
|
||||
* The safeBlockingMigrationsBlock block will
|
||||
* run any outstanding version migrations that are a) blocking and b) safe
|
||||
* to be run before the environment and storage is completely configured.
|
||||
*
|
||||
* Specifically, these migration should not depend on or affect the data
|
||||
* of any database view.
|
||||
*/
|
||||
- (void)setupDatabaseWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock;
|
||||
|
||||
- (YapDatabaseConnection *)dbReadConnection;
|
||||
- (YapDatabaseConnection *)dbReadWriteConnection;
|
||||
+ (YapDatabaseConnection *)dbReadConnection;
|
||||
|
|
|
@ -28,6 +28,9 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
|||
@property (nonatomic, readonly) YapDatabaseConnection *dbReadConnection;
|
||||
@property (nonatomic, readonly) YapDatabaseConnection *dbReadWriteConnection;
|
||||
|
||||
@property (atomic) BOOL areAsyncRegistrationsComplete;
|
||||
@property (atomic) BOOL areSyncRegistrationsComplete;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
@ -69,7 +72,7 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
|||
[super resetStorage];
|
||||
}
|
||||
|
||||
- (void)setupDatabaseWithSafeBlockingMigrations:(void (^_Nonnull)(void))safeBlockingMigrationsBlock
|
||||
- (void)runSyncRegistrations
|
||||
{
|
||||
// Synchronously register extensions which are essential for views.
|
||||
[TSDatabaseView registerCrossProcessNotifier];
|
||||
|
@ -86,15 +89,13 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
|||
// seeing, this issue only seems to affect sync and not async registrations. We've always
|
||||
// been opening write transactions before the async registrations complete without negative
|
||||
// consequences.
|
||||
[self setSyncRegistrationsAreComplete];
|
||||
OWSAssert(!self.areSyncRegistrationsComplete);
|
||||
self.areSyncRegistrationsComplete = YES;
|
||||
}
|
||||
|
||||
// Run the blocking migrations.
|
||||
//
|
||||
// These need to run _before_ the async registered database views or
|
||||
// they will block on them, which (in the upgrade case) can block
|
||||
// return of appDidFinishLaunching... which in term can cause the
|
||||
// app to crash on launch.
|
||||
safeBlockingMigrationsBlock();
|
||||
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion
|
||||
{
|
||||
OWSAssert(completion);
|
||||
|
||||
// Asynchronously register other extensions.
|
||||
//
|
||||
|
@ -111,10 +112,14 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
|||
[OWSFailedMessagesJob asyncRegisterDatabaseExtensionsWithStorageManager:self];
|
||||
[OWSFailedAttachmentDownloadsJob asyncRegisterDatabaseExtensionsWithStorageManager:self];
|
||||
|
||||
// NOTE: [TSDatabaseView asyncRegistrationCompletion] ensures that
|
||||
// DatabaseViewRegistrationCompleteNotification is not fired until all
|
||||
// of the async registrations are complete.
|
||||
[TSDatabaseView asyncRegistrationCompletion];
|
||||
// Block until all async registrations are complete.
|
||||
[self.newDatabaseConnection asyncReadWriteWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
|
||||
OWSAssert(!self.areAsyncRegistrationsComplete);
|
||||
|
||||
self.areAsyncRegistrationsComplete = YES;
|
||||
|
||||
completion();
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)protectFiles
|
||||
|
@ -216,12 +221,12 @@ NSString *const TSStorageManagerExceptionName_CouldNotCreateDatabaseDirectory
|
|||
|
||||
+ (YapDatabaseConnection *)dbReadConnection
|
||||
{
|
||||
return TSStorageManager.dbReadConnection;
|
||||
return TSStorageManager.sharedManager.dbReadConnection;
|
||||
}
|
||||
|
||||
+ (YapDatabaseConnection *)dbReadWriteConnection
|
||||
{
|
||||
return TSStorageManager.dbReadWriteConnection;
|
||||
return TSStorageManager.sharedManager.dbReadWriteConnection;
|
||||
}
|
||||
|
||||
- (void)deleteDatabaseFile
|
||||
|
|
|
@ -102,8 +102,8 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE
|
|||
OWSContactsSyncing.sharedManager()
|
||||
|
||||
NotificationCenter.default.addObserver(self,
|
||||
selector: #selector(databaseViewRegistrationComplete),
|
||||
name: .DatabaseViewRegistrationComplete,
|
||||
selector: #selector(storageIsReady),
|
||||
name: .StorageIsReady,
|
||||
object: nil)
|
||||
NotificationCenter.default.addObserver(self,
|
||||
selector: #selector(registrationStateDidChange),
|
||||
|
@ -177,7 +177,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE
|
|||
}
|
||||
|
||||
@objc
|
||||
func databaseViewRegistrationComplete() {
|
||||
func storageIsReady() {
|
||||
AssertIsOnMainThread()
|
||||
|
||||
Logger.debug("\(self.logTag) \(#function)")
|
||||
|
@ -232,7 +232,7 @@ public class ShareViewController: UINavigationController, ShareViewDelegate, SAE
|
|||
private func ensureRootViewController() {
|
||||
Logger.debug("\(self.logTag) \(#function)")
|
||||
|
||||
guard !TSDatabaseView.hasPendingViewRegistrations() else {
|
||||
guard OWSStorage.isStorageReady() else {
|
||||
return
|
||||
}
|
||||
guard !hasInitialRootViewController else {
|
||||
|
|
Loading…
Reference in a new issue