Merge pull request #2527 from vitorpamplona/claude/remove-group-on-leave-JTVQb
Fix memory leak when leaving Marmot groups
This commit is contained in:
@@ -2319,6 +2319,12 @@ class Account(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val outbound = manager.leaveGroup(nostrGroupId)
|
val outbound = manager.leaveGroup(nostrGroupId)
|
||||||
|
// manager.leaveGroup already wiped MLS state, relay subscriptions and
|
||||||
|
// the persisted message log. Drop the in-memory chatroom too — that
|
||||||
|
// releases the strong refs to the decrypted inner notes so LocalCache
|
||||||
|
// (which holds them weakly) can GC them, and the Notification feed
|
||||||
|
// (which iterates marmotGroupList.rooms) stops surfacing the group.
|
||||||
|
marmotGroupList.removeGroup(nostrGroupId)
|
||||||
client.publish(outbound.signedEvent, groupRelays)
|
client.publish(outbound.signedEvent, groupRelays)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-1
@@ -316,7 +316,6 @@ fun MarmotGroupInfoScreen(
|
|||||||
scope.launch(Dispatchers.IO) {
|
scope.launch(Dispatchers.IO) {
|
||||||
try {
|
try {
|
||||||
accountViewModel.leaveMarmotGroup(nostrGroupId)
|
accountViewModel.leaveMarmotGroup(nostrGroupId)
|
||||||
accountViewModel.account.marmotGroupList.removeGroup(nostrGroupId)
|
|
||||||
nav.nav(Route.Message)
|
nav.nav(Route.Message)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
isLeaving = false
|
isLeaving = false
|
||||||
|
|||||||
+17
@@ -202,4 +202,21 @@ class MarmotGroupChatroom(
|
|||||||
changesFlow.get()?.tryEmit(ListChange.SetDeletion<Note>(toRemove))
|
changesFlow.get()?.tryEmit(ListChange.SetDeletion<Note>(toRemove))
|
||||||
return toRemove
|
return toRemove
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop every message from this chatroom. Used when the local user leaves
|
||||||
|
* the group: cuts the strong references held in [messages] so the
|
||||||
|
* decrypted inner notes become eligible for GC out of LocalCache (which
|
||||||
|
* holds them weakly).
|
||||||
|
*/
|
||||||
|
@Synchronized
|
||||||
|
fun clearAllMessagesSync(): Set<Note> {
|
||||||
|
val toRemove = messages
|
||||||
|
if (toRemove.isEmpty()) return toRemove
|
||||||
|
messages = emptySet()
|
||||||
|
newestMessage = null
|
||||||
|
unreadCount.value = 0
|
||||||
|
changesFlow.get()?.tryEmit(ListChange.SetDeletion<Note>(toRemove))
|
||||||
|
return toRemove
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -127,8 +127,15 @@ class MarmotGroupList(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop a group from the in-memory list. Also clears the chatroom's own
|
||||||
|
* message set and the note→group index: LocalCache holds notes weakly, so
|
||||||
|
* once these strong references go away the decrypted inner messages
|
||||||
|
* become eligible for GC and stop appearing in the Notification feed.
|
||||||
|
*/
|
||||||
fun removeGroup(nostrGroupId: HexKey) {
|
fun removeGroup(nostrGroupId: HexKey) {
|
||||||
rooms.remove(nostrGroupId)
|
val chatroom = rooms.remove(nostrGroupId)
|
||||||
|
chatroom?.clearAllMessagesSync()?.forEach { noteToGroupIndex.remove(it.idHex) }
|
||||||
_groupListChanges.tryEmit(nostrGroupId)
|
_groupListChanges.tryEmit(nostrGroupId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user