Skip to content

Commit 598bc55

Browse files
author
Greg Soltis
authored
Remove start from persistence interface (#2173)
* Remove start from persistence interface, switch FSTLevelDB to use a factory method that returns Status
1 parent 2bce70d commit 598bc55

File tree

6 files changed

+71
-93
lines changed

6 files changed

+71
-93
lines changed

Firestore/Example/Tests/Local/FSTPersistenceTestHelpers.mm

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,14 @@ + (FSTLevelDB *)levelDBPersistenceWithDir:(Path)dir {
6868

6969
+ (FSTLevelDB *)levelDBPersistenceWithDir:(Path)dir lruParams:(LruParams)params {
7070
FSTLocalSerializer *serializer = [self localSerializer];
71-
FSTLevelDB *db =
72-
[[FSTLevelDB alloc] initWithDirectory:std::move(dir) serializer:serializer lruParams:params];
73-
Status status = [db start];
71+
FSTLevelDB *ldb;
72+
util::Status status =
73+
[FSTLevelDB dbWithDirectory:std::move(dir) serializer:serializer lruParams:params ptr:&ldb];
7474
if (!status.ok()) {
7575
[NSException raise:NSInternalInconsistencyException
76-
format:@"Failed to start leveldb persistence: %s", status.ToString().c_str()];
76+
format:@"Failed to open DB: %s", status.ToString().c_str()];
7777
}
78-
79-
return db;
78+
return ldb;
8079
}
8180

8281
+ (FSTLevelDB *)levelDBPersistenceWithLruParams:(LruParams)lruParams {
@@ -88,14 +87,7 @@ + (FSTLevelDB *)levelDBPersistence {
8887
}
8988

9089
+ (FSTMemoryPersistence *)eagerGCMemoryPersistence {
91-
FSTMemoryPersistence *persistence = [FSTMemoryPersistence persistenceWithEagerGC];
92-
Status status = [persistence start];
93-
if (!status.ok()) {
94-
[NSException raise:NSInternalInconsistencyException
95-
format:@"Failed to start memory persistence: %s", status.ToString().c_str()];
96-
}
97-
98-
return persistence;
90+
return [FSTMemoryPersistence persistenceWithEagerGC];
9991
}
10092

10193
+ (FSTMemoryPersistence *)lruMemoryPersistence {
@@ -104,15 +96,7 @@ + (FSTMemoryPersistence *)lruMemoryPersistence {
10496

10597
+ (FSTMemoryPersistence *)lruMemoryPersistenceWithLruParams:(LruParams)lruParams {
10698
FSTLocalSerializer *serializer = [self localSerializer];
107-
FSTMemoryPersistence *persistence =
108-
[FSTMemoryPersistence persistenceWithLruParams:lruParams serializer:serializer];
109-
Status status = [persistence start];
110-
if (!status.ok()) {
111-
[NSException raise:NSInternalInconsistencyException
112-
format:@"Failed to start memory persistence: %s", status.ToString().c_str()];
113-
}
114-
115-
return persistence;
99+
return [FSTMemoryPersistence persistenceWithLruParams:lruParams serializer:serializer];
116100
}
117101

118102
@end

Firestore/Source/Core/FSTFirestoreClient.mm

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -199,27 +199,27 @@ - (void)initializeWithUser:(const User &)user settings:(FIRFirestoreSettings *)s
199199
[[FSTSerializerBeta alloc] initWithDatabaseID:&self.databaseInfo->database_id()];
200200
FSTLocalSerializer *serializer =
201201
[[FSTLocalSerializer alloc] initWithRemoteSerializer:remoteSerializer];
202-
FSTLevelDB *ldb =
203-
[[FSTLevelDB alloc] initWithDirectory:std::move(dir)
204-
serializer:serializer
205-
lruParams:LruParams::WithCacheSize(settings.cacheSizeBytes)];
202+
FSTLevelDB *ldb;
203+
Status levelDbStatus =
204+
[FSTLevelDB dbWithDirectory:std::move(dir)
205+
serializer:serializer
206+
lruParams:LruParams::WithCacheSize(settings.cacheSizeBytes)
207+
ptr:&ldb];
208+
if (!levelDbStatus.ok()) {
209+
// If leveldb fails to start then just throw up our hands: the error is unrecoverable.
210+
// There's nothing an end-user can do and nearly all failures indicate the developer is doing
211+
// something grossly wrong so we should stop them cold in their tracks with a failure they
212+
// can't ignore.
213+
[NSException raise:NSInternalInconsistencyException
214+
format:@"Failed to open DB: %s", levelDbStatus.ToString().c_str()];
215+
}
206216
_lruDelegate = ldb.referenceDelegate;
207217
_persistence = ldb;
208218
[self scheduleLruGarbageCollection];
209219
} else {
210220
_persistence = [FSTMemoryPersistence persistenceWithEagerGC];
211221
}
212222

213-
Status status = [_persistence start];
214-
if (!status.ok()) {
215-
// If local storage fails to start then just throw up our hands: the error is unrecoverable.
216-
// There's nothing an end-user can do and nearly all failures indicate the developer is doing
217-
// something grossly wrong so we should stop them cold in their tracks with a failure they
218-
// can't ignore.
219-
[NSException raise:NSInternalInconsistencyException
220-
format:@"Failed to open DB: %s", status.ToString().c_str()];
221-
}
222-
223223
_localStore = [[FSTLocalStore alloc] initWithPersistence:_persistence initialUser:user];
224224

225225
FSTDatastore *datastore = [FSTDatastore datastoreWithDatabase:self.databaseInfo

Firestore/Source/Local/FSTLevelDB.h

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h"
2727
#include "Firestore/core/src/firebase/firestore/util/path.h"
2828
#include "Firestore/core/src/firebase/firestore/util/status.h"
29+
#include "Firestore/core/src/firebase/firestore/util/statusor.h"
2930
#include "leveldb/db.h"
3031

3132
@class FSTLocalSerializer;
@@ -40,13 +41,16 @@ NS_ASSUME_NONNULL_BEGIN
4041
@interface FSTLevelDB : NSObject <FSTPersistence, FSTTransactional>
4142

4243
/**
43-
* Initializes the LevelDB in the given directory. Note that all expensive startup work including
44-
* opening any database files is deferred until -[FSTPersistence start] is called.
44+
* Creates a LevelDB in the given directory and sets `ptr` to point to it. Return value indicates
45+
* success in creating the leveldb instance and must be checked before accessing `ptr`. C++ note:
46+
* Once FSTLevelDB is ported to C++, this factory method should return StatusOr<>. It cannot
47+
* currently do that because ObjC references are not allowed in StatusOr.
4548
*/
46-
- (instancetype)initWithDirectory:(firebase::firestore::util::Path)directory
47-
serializer:(FSTLocalSerializer *)serializer
48-
lruParams:(firebase::firestore::local::LruParams)lruParams
49-
NS_DESIGNATED_INITIALIZER;
49+
+ (firebase::firestore::util::Status)dbWithDirectory:(firebase::firestore::util::Path)directory
50+
serializer:(FSTLocalSerializer *)serializer
51+
lruParams:
52+
(firebase::firestore::local::LruParams)lruParams
53+
ptr:(FSTLevelDB **)ptr;
5054

5155
- (instancetype)init NS_UNAVAILABLE;
5256

@@ -65,15 +69,6 @@ NS_ASSUME_NONNULL_BEGIN
6569
storageDirectoryForDatabaseInfo:(const firebase::firestore::core::DatabaseInfo &)databaseInfo
6670
documentsDirectory:(const firebase::firestore::util::Path &)documentsDirectory;
6771

68-
/**
69-
* Starts LevelDB-backed persistent storage by opening the database files, creating the DB if it
70-
* does not exist.
71-
*
72-
* The leveldb directory is created relative to the appropriate document storage directory for the
73-
* platform: NSDocumentDirectory on iOS or $HOME/.firestore on macOS.
74-
*/
75-
- (firebase::firestore::util::Status)start;
76-
7772
/**
7873
* @return A standard set of read options
7974
*/

Firestore/Source/Local/FSTLevelDB.mm

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -299,16 +299,50 @@ + (const ReadOptions)standardReadOptions {
299299
return users;
300300
}
301301

302-
- (instancetype)initWithDirectory:(firebase::firestore::util::Path)directory
303-
serializer:(FSTLocalSerializer *)serializer
304-
lruParams:(firebase::firestore::local::LruParams)lruParams {
302+
+ (firebase::firestore::util::Status)dbWithDirectory:(firebase::firestore::util::Path)directory
303+
serializer:(FSTLocalSerializer *)serializer
304+
lruParams:
305+
(firebase::firestore::local::LruParams)lruParams
306+
ptr:(FSTLevelDB **)ptr {
307+
Status status = [self ensureDirectory:directory];
308+
if (!status.ok()) return status;
309+
310+
StatusOr<std::unique_ptr<DB>> database = [self createDBWithDirectory:directory];
311+
if (!database.status().ok()) {
312+
return database.status();
313+
}
314+
315+
std::unique_ptr<DB> ldb = std::move(database.ValueOrDie());
316+
LevelDbMigrations::RunMigrations(ldb.get());
317+
LevelDbTransaction transaction(ldb.get(), "Start LevelDB");
318+
std::set<std::string> users = [self collectUserSet:&transaction];
319+
transaction.Commit();
320+
FSTLevelDB *db = [[self alloc] initWithLevelDB:std::move(ldb)
321+
users:users
322+
directory:directory
323+
serializer:serializer
324+
lruParams:lruParams];
325+
*ptr = db;
326+
return Status::OK();
327+
}
328+
329+
- (instancetype)initWithLevelDB:(std::unique_ptr<leveldb::DB>)db
330+
users:(std::set<std::string>)users
331+
directory:(firebase::firestore::util::Path)directory
332+
serializer:(FSTLocalSerializer *)serializer
333+
lruParams:(firebase::firestore::local::LruParams)lruParams {
305334
if (self = [super init]) {
335+
self.started = YES;
336+
_ptr = std::move(db);
306337
_directory = std::move(directory);
307338
_serializer = serializer;
308339
_queryCache = [[FSTLevelDBQueryCache alloc] initWithDB:self serializer:self.serializer];
309340
_referenceDelegate =
310341
[[FSTLevelDBLRUDelegate alloc] initWithPersistence:self lruParams:lruParams];
311342
_transactionRunner.SetBackingPersistence(self);
343+
_users = std::move(users);
344+
[_queryCache start];
345+
[_referenceDelegate start];
312346
}
313347
return self;
314348
}
@@ -376,30 +410,8 @@ + (Path)storageDirectoryForDatabaseInfo:(const DatabaseInfo &)databaseInfo
376410

377411
#pragma mark - Startup
378412

379-
- (Status)start {
380-
HARD_ASSERT(!self.isStarted, "FSTLevelDB double-started!");
381-
self.started = YES;
382-
383-
Status status = [self ensureDirectory:_directory];
384-
if (!status.ok()) return status;
385-
386-
StatusOr<std::unique_ptr<DB>> database = [self createDBWithDirectory:_directory];
387-
if (!database.status().ok()) {
388-
return database.status();
389-
}
390-
_ptr = std::move(database).ValueOrDie();
391-
392-
LevelDbMigrations::RunMigrations(_ptr.get());
393-
LevelDbTransaction transaction(_ptr.get(), "Start LevelDB");
394-
_users = [FSTLevelDB collectUserSet:&transaction];
395-
transaction.Commit();
396-
[_queryCache start];
397-
[_referenceDelegate start];
398-
return Status::OK();
399-
}
400-
401413
/** Creates the directory at @a directory and marks it as excluded from iCloud backup. */
402-
- (Status)ensureDirectory:(const Path &)directory {
414+
+ (Status)ensureDirectory:(const Path &)directory {
403415
Status status = util::RecursivelyCreateDir(directory);
404416
if (!status.ok()) {
405417
return Status{FirestoreErrorCode::Internal, "Failed to create persistence directory"}.CausedBy(
@@ -418,7 +430,7 @@ - (Status)ensureDirectory:(const Path &)directory {
418430
}
419431

420432
/** Opens the database within the given directory. */
421-
- (StatusOr<std::unique_ptr<DB>>)createDBWithDirectory:(const Path &)directory {
433+
+ (StatusOr<std::unique_ptr<DB>>)createDBWithDirectory:(const Path &)directory {
422434
Options options;
423435
options.create_if_missing = true;
424436

Firestore/Source/Local/FSTMemoryPersistence.mm

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ - (instancetype)init {
9999
if (self = [super init]) {
100100
_queryCache = [[FSTMemoryQueryCache alloc] initWithPersistence:self];
101101
_remoteDocumentCache = [[FSTMemoryRemoteDocumentCache alloc] init];
102+
self.started = YES;
102103
}
103104
return self;
104105
}
@@ -111,13 +112,6 @@ - (void)setReferenceDelegate:(id<FSTReferenceDelegate>)referenceDelegate {
111112
}
112113
}
113114

114-
- (Status)start {
115-
// No durable state to read on startup.
116-
HARD_ASSERT(!self.isStarted, "FSTMemoryPersistence double-started!");
117-
self.started = YES;
118-
return Status::OK();
119-
}
120-
121115
- (void)shutdown {
122116
// No durable state to ensure is closed on shutdown.
123117
HARD_ASSERT(self.isStarted, "FSTMemoryPersistence shutdown without start!");

Firestore/Source/Local/FSTPersistence.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,6 @@ NS_ASSUME_NONNULL_BEGIN
6565
*/
6666
@protocol FSTPersistence <NSObject>
6767

68-
/**
69-
* Starts persistent storage, opening the database or similar.
70-
*
71-
* @return A Status object that will be populated with an error message if startup fails.
72-
*/
73-
- (firebase::firestore::util::Status)start;
74-
7568
/** Releases any resources held during eager shutdown. */
7669
- (void)shutdown;
7770

0 commit comments

Comments
 (0)