Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix rare crashes when deleting local database content on logout #3355

Merged
merged 1 commit into from
Aug 2, 2024

Conversation

laevandus
Copy link
Contributor

@laevandus laevandus commented Aug 1, 2024

🔗 Issue Links

Resolves PBE-4309

🎯 Goal

Fix crashes on logout related to local database access

📝 Summary

  • Notify NSManagedObjectContext that data was deleted on the SQL level
  • Discard any DatabaseContainer write requests while clearing local data

🛠 Implementation

Batch delete removes data on the SQL level and does not notify contexts. Contexts can be left into invalid state if we do not manually notify them.

🧪 Manual Testing Notes

Repeat

  1. Log in
  2. Do something
  3. Log out

No crashes or any other odd things should appear.

☑️ Contributor Checklist

  • I have signed the Stream CLA (required)
  • This change should be manually QAed
  • Changelog is updated with client-facing changes
  • Changelog is updated with new localization keys
  • New code is covered by unit tests
  • Comparison screenshots added for visual changes
  • Affected documentation updated (docusaurus, tutorial, CMS)

@laevandus laevandus added 🐞 Bug An issue or PR related to a bug 🌐 SDK: StreamChat (LLC) Tasks related to the StreamChat LLC SDK 🤞 Ready For QA A PR that is Ready for QA labels Aug 1, 2024
@laevandus laevandus requested a review from a team as a code owner August 1, 2024 12:50
Comment on lines +221 to +225
guard self.canWriteData else {
log.debug("Discarding write attempt.", subsystems: .database)
completion(nil)
return
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a safeguard here for cases where batch delete is in process and some delayed action triggers database write.

Comment on lines +138 to +141
// Save just after triggering remove all
container.write { session in
try session.saveChannel(payload: self.dummyPayload(with: .unique), query: nil, cache: nil)
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without canWriteData this would cause a test failure in this test (but sometimes, because this depends on the timing. I got test failures when I repeated the test 100 times)

@Stream-SDK-Bot
Copy link
Collaborator

SDK Size

title develop branch diff status
StreamChat 6.76MB 6.76MB 0.0MB 🟢
StreamChatUI 4.41MB 4.41MB 0.0MB 🟢

@Stream-SDK-Bot
Copy link
Collaborator

SDK Performance

target metric benchmark branch performance status
MessageList Hitches total duration 10 ms 1.67 ms 83.3% 🔼 🟢
Duration 2.6 s 2.54 s 2.31% 🔼 🟢
Hitch time ratio 4 ms per s 0.66 ms per s 83.5% 🔼 🟢
Frame rate 75 fps 78.03 fps 4.04% 🔼 🟢
Number of hitches 1 0.2 80.0% 🔼 🟢
ChannelList Hitches total duration 12.5 ms 12.52 ms -0.16% 🔽 🟡
Duration 2.6 s 2.56 s 1.54% 🔼 🟢
Hitch time ratio 5 ms per s 4.88 ms per s 2.4% 🔼 🟢
Frame rate 72 fps 74.24 fps 3.11% 🔼 🟢
Number of hitches 1.2 1.0 16.67% 🔼 🟢

@Stream-SDK-Bot
Copy link
Collaborator

Stream-SDK-Bot commented Aug 1, 2024

SDK Size

title develop branch diff status
StreamChat 6.76MB 6.76MB 0.0MB 🟢
StreamChatUI 4.41MB 4.41MB 0.0MB 🟢

Copy link
Member

@nuno-vieira nuno-vieira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM ✅ Just added a couple suggestions, but nothing blocking 👍

@@ -193,6 +119,45 @@ final class DatabaseContainer_Tests: XCTestCase {
}
}
}

func test_removingAllData_whileAnotherWrite() throws {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we maybe add a test or try in our Demo App to logout while there is another controller reference alive and then access that controller's data? 🤔 It would be interesting to see if it previously crashed, and now it does not. Although it might be tricky to actually reproduce this 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I should be able to create a test for this.

  1. Create controller
  2. Write some data
  3. Call remove all
  4. When remove is done, accessing controller content

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a test what fails without current changes.

@laevandus laevandus force-pushed the fix/log-out-db-delete branch 2 times, most recently from cdfeaa3 to 3a830b4 Compare August 2, 2024 08:02
@testableapple testableapple added the 🟢 QAed A PR that was QAed label Aug 2, 2024
@laevandus laevandus removed the 🤞 Ready For QA A PR that is Ready for QA label Aug 2, 2024
@laevandus laevandus enabled auto-merge (squash) August 2, 2024 11:26
Copy link

sonarcloud bot commented Aug 2, 2024

@laevandus laevandus merged commit 6a7eb0e into develop Aug 2, 2024
15 checks passed
@laevandus laevandus deleted the fix/log-out-db-delete branch August 2, 2024 12:03
@Stream-SDK-Bot Stream-SDK-Bot mentioned this pull request Aug 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐞 Bug An issue or PR related to a bug 🟢 QAed A PR that was QAed 🌐 SDK: StreamChat (LLC) Tasks related to the StreamChat LLC SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants