Tapping the Notifications tab sometimes causes the app to hang
Sometimes when I tap the Notifications tab, the app just hangs. I've seen this in the debugger before, and I think it may be related to multiple managed object contexts trying to save at the same time. But I could be wrong.
Steps to reproduce:
- Launch the app
- While the Feed or Discover tab is still loading, tap the Notifications tab
- If you're (un)lucky, the app will freeze up
- If you're super lucky, you'll be in debug mode and be able to see what's happening
Just happened to me again, but I don't have any better steps to reproduce. This happened after I logged out of a throwaway test account and logged into my personal one. It's hung on the Notifications tab with a bunch of missing data:
When I pause in the debugger, I see it stop on the line in the screenshot below. When I continue running and pause again, it stops on this line again, every time.
This seems to indicate to me that the save is waiting on something that never seems to finish. Deadlock, maybe?
I wonder if it's in these lines (from NotificationsView.swift):
let backgroundContext = persistenceController.backgroundViewContext
try await NosNotification.markAllAsRead(for: user, in: backgroundContext)
await pushNotificationService.updateBadgeCount()
As you can see in the screen shot, the badge hasn't been updated, so I wonder if it's waiting for the try await NosNotification.markAllAsRead(...) to finish and it's just not.
I just had the app hang again. This time it's in my open PR where I added code that uses persistenceController.saveAll(). Here's the commit and the line that's hanging (again, based on pausing in the debugger, continuing, pausing again, and seeing the same line): https://github.com/planetary-social/nos/pull/1100/commits/5ee3b94d231c2e0d04314fd4757108f9c70f06e1#diff-437396bafa74ddc6f1556cd6b30eff884465099690729e1c8e685ada4602cf1cR148
I think there's a problem in one of the following:
PersistenceController.saveAll()NSManagedObjectContext.saveIfNeeded(), which is called byPersistenceController.saveAll()
This looks similar to the deadlock I experienced when working on https://github.com/planetary-social/nos/pull/696. I never figured out what was wrong but I think it had to do with NSManagedObjectContexts trying to lock things so they could do a save, and two of them trying to lock on the same thread. Maybe that's not what's going on here but it's a place to look.