fix(navigation): reset graph state after client removal [WPB-27228] [WPB-27362] - #5084
fix(navigation): reset graph state after client removal [WPB-27228] [WPB-27362]#5084MohamadJaara wants to merge 3 commits into
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #5084 +/- ##
===========================================
+ Coverage 49.53% 49.60% +0.06%
===========================================
Files 659 659
Lines 24007 24019 +12
Branches 3733 3735 +2
===========================================
+ Hits 11893 11915 +22
+ Misses 10984 10974 -10
Partials 1130 1130
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
| val backgroundType = currentBackStackEntryState.value?.safeDestination()?.style.let { | ||
| (it as? BackgroundStyle)?.backgroundType() ?: BackgroundType.Default |
There was a problem hiding this comment.
Why not a derivedStateOf anymore?
| } | ||
|
|
||
| @Composable | ||
| internal fun rememberWireActivityCurrentBackStackEntryState( |
There was a problem hiding this comment.
It doesn't actually use remember, so maybe remove the "remember" prefix from the name? 🤔
| ): WireActivityGraphContext? { | ||
| if (!shouldInvalidate) return lastSessionGraphContext | ||
|
|
||
| lastSessionGraphContext?.sessionGraph?.currentAccount?.let(sessionGraphStore::invalidate) |
There was a problem hiding this comment.
Could we avoid relying exclusively on lastSessionGraphContext to identify the graph to invalidate?
SessionGraphStoreViewModel survives an Activity recreation, while lastSessionGraphContext is held with Compose remember and is reset. If the Activity is recreated while a terminal error is already blocking the UI, rememberWireActivityGraphContext() returns null, so this value is never restored and the retained graph remains in sessionGraphs.
Logging the same user in again then returns the old RetainedSessionGraph from getOrPut(), including its session-scoped state.
I reproduced this with a unit test: retain a graph, simulate recreation by losing the remembered context while keeping the store, trigger invalidation, and request the same user again. It fails with:
expected: not same but was: <RetainedSessionGraph@...>
Could the store retain enough information to invalidate the affected user independently of the composition state, or invalidate all retained graphs for a terminal session transition?
https://wearezeta.atlassian.net/browse/WPB-27228
Intent
Make removed-client recovery safe while the app process remains alive: rebuild navigation from synchronized session state, discard all state owned by the invalid session, and allow the same user to log in again with a fresh Kalium session.
Depends on wireapp/kalium#4318.
Reproduction
Root cause
The navigation controller was replaced in place while Compose could still expose the old back-stack entry. That stale route could trigger navigation against the new graphless controller.
The activity also retained its session graph and activity-scoped view models for the process lifetime. Removing a client did not invalidate those objects, so logging the same user in again could reuse dependencies and resources tied to the destroyed Kalium session.
flowchart LR A["Remote client removal"] --> B["Block session UI"] B --> C["Confirm dialog"] C --> D["Invalidate retained graph"] D --> E["Clear session view models and image loader"] E --> F["Rebuild authentication graph"] F --> G["Login same user"] G --> H["Create fresh app and Kalium session state"] H --> I["Join MLS conversations"]Changes
ViewModelStoreand session image loader lifetime.Coverage