-
Notifications
You must be signed in to change notification settings - Fork 39
Fix retain cycle in Client #550
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
base: main
Are you sure you want to change the base?
Conversation
Break the Client retain cycle by making
|
|
Claude finished @yewreeka's task —— View job Code Review CompleteI've thoroughly analyzed the retain cycle fix in this PR. Here's my comprehensive feedback: ✅ Overall AssessmentThis PR successfully fixes the retain cycles between 📋 What Changed1.
2.
3.
4.
🎯 Strengths1. Appropriate Use of Different Strategies
2. Proper Error Handling ( private func requireClient() throws -> Client {
guard let client = client else {
throw ClientError.clientDeallocated
}
return client
}Excellent pattern - provides clear error feedback when client is deallocated. 3. Added 4. Privacy Improvement ( 5. Fixed Critical NSMapTable Bug
|
| Aspect | Rating | Notes |
|---|---|---|
| Retain Cycle Fix | ✅ Excellent | All cycles properly broken |
| Architecture | ✅ Good | Right strategy for each case |
| Memory Safety | Needs weak checks in streams | |
| Error Handling | ✅ Good | requireClient() pattern is clean |
| Code Quality | ✅ High | Clean, readable changes |
| Bug Fixes | ✅ Excellent | Fixed NSMapTable bug |
| Test Coverage | Add deallocation edge case tests |
🎯 Action Items
Recommended before merge:
⚠️ Add nil checks in stream callback closures (stream(),streamAllMessages())⚠️ AddrequireClient()calls to public methods that useffiClient/ffiConversations, or document why it's safe to skip
Nice to have:
3. 💡 Clarify/document whether strong caching of XmtpApiClient is intentional
4. 💡 Add unit tests for client deallocation scenarios
5. 💡 Resolve/respond to macroscopeapp's review comments (the NSMapTable one is addressed, the unowned one is outdated)
✨ Conclusion
This is a well-thought-out fix that appropriately addresses the retain cycle issue. The choice to:
- Remove the
Clientreference fromPrivatePreferencesentirely (cleanest!) - Remove it from
XMTPDebugInformation(also clean!) - Use
weakwith proper error handling forConversations(necessary and well-done!) - Fix the
NSMapTablebug inApiClientCache(great catch!)
...shows excellent architectural judgment.
The main concerns are around ensuring weak reference handling is complete in all code paths, particularly in streaming scenarios. With those minor improvements, this PR will be production-ready.
Great work on identifying and fixing these cycles! 🎉
cameronvoell
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for finding this @jarodl . I added small change to remove the client reference from debuginformation. I also made the client reference in Conversations private, to minimize the chance of someone trying to acceess it when it's not available.
There is a small chance an integrator uses the SDK in an untended way holding a reference to a client.conversations() and then trying to use it when the client is not in memory. But hopefully suggested use cases in our docs will make that rare enough, so still think fixing memory leak possibilities here is the better way to go.
If you can suggest a follow up at some point to pass in some context provider instead of the client so we dont have the risk of someone trying to access the unowned client reference when its not available, that would be awesome. But this is a great improvement 👍
581505d to
061222b
Compare
I updated this to use a |
Introduction 📟
Clientkept a strong reference toConversations,PrivatePreferences, andXMTPDebugInformation, all which kept a strong reference toClient. I also noticed thatXmtpApiClientobjects hang around because ofApiClientCache, but not sure if that's really an issue worth worrying about.Purpose ℹ️
Fix retain cycle in
ClientTesting 🧪
Ran tests and checked the memory graph in the
exampleapp