Skip to content

Commit

Permalink
Remove stale promises from the DB on app startup
Browse files Browse the repository at this point in the history
Before this commit, promises were only removed from the DB once they
were consumed.

Therefore, it was possible to end up with "stale" promises lingering in
the promise table of the DB, if the promise was created and persisted,
but the app got closed before they could be consumed.

These promises would linger forever because there was no way to consume
them anymore (resolvers map was empty) and would therefore just take up
space in the table for no reason.

This commit fixes this by truncating the promise table on each restart
of the application. We can truncate the whole table as we know that all
of the promises still in the DB at app start-up are unconsumable, as
the resolvers map will be empty at this point.
  • Loading branch information
matthewrfennell authored and tmolitor-stud-tu committed Dec 27, 2024
1 parent 4ab6f16 commit 44e052e
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 0 deletions.
1 change: 1 addition & 0 deletions Monal/Classes/DataLayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ extern NSString* const kMessageTypeFiletransfer;

-(void) addPromise:(MLPromise*) promise;
-(void) removePromise:(MLPromise*) promise;
-(void) removeAllPromises;
-(MLPromise*) getPromise:(MLPromise*) promise;

@end
Expand Down
9 changes: 9 additions & 0 deletions Monal/Classes/DataLayer.m
Original file line number Diff line number Diff line change
Expand Up @@ -2561,6 +2561,15 @@ -(void) removePromise:(MLPromise*) promise
}];
}

-(void) removeAllPromises
{
DDLogDebug(@"Removing all promises from the DB");
[self.db voidWriteTransaction:^{
NSString* query = @"DELETE FROM promises;";
[self.db executeNonQuery:query];
}];
}

-(MLPromise*) getPromise:(MLPromise*) promise
{
DDLogDebug(@"Getting promise %@ with uuid %@ from DB", promise, promise.uuid);
Expand Down
2 changes: 2 additions & 0 deletions Monal/Classes/MLPromise.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ NS_ASSUME_NONNULL_BEGIN
-(void) reject:(NSError*) error;
-(AnyPromise*) toAnyPromise;

+(void) removeStalePromises;

@end

NS_ASSUME_NONNULL_END
9 changes: 9 additions & 0 deletions Monal/Classes/MLPromise.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ -(void) deserialize
[self attemptConsume];
}

// A stale promise is a promise that is still in the DB, but doesn't have an entry in the resolvers map.
// It is "stale" because it is not possible to consume it - we've lost the linkage from MLPromise to AnyPromise that _resolvers provides.
// When we start the app, the resolvers map is empty; therefore, all promises still in the DB are stale.
+(void) removeStalePromises
{
MLAssert([_resolvers count] == 0, @"Resolvers map should be empty, but it was not. This function should only be called on app start-up");
[[DataLayer sharedInstance] removeAllPromises];
}

-(void) resolve:(id _Nullable) argument
{
DDLogDebug(@"Resolving promise %@ with uuid %@ and argument %@", self, self.uuid, argument);
Expand Down
3 changes: 3 additions & 0 deletions Monal/Classes/MonalAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,9 @@ -(BOOL) application:(UIApplication*) application willFinishLaunchingWithOptions:
[[MLImageManager sharedInstance] cleanupHashes];
});

// Remove stale promises left in the DB that weren't consumed last time we ran the app
[MLPromise removeStalePromises];

//only proceed with launching if the NotificationServiceExtension is *not* running
if([MLProcessLock checkRemoteRunning:@"NotificationServiceExtension"])
{
Expand Down

0 comments on commit 44e052e

Please sign in to comment.