mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-11-10 02:37:22 +01:00
Merge pull request #1550 from davotoula/reduce-errors-ConcurrentModificationException
Reduce errors in log: concurrent modification exception
This commit is contained in:
@@ -46,7 +46,6 @@ import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.flow.transformLatest
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlin.collections.map
|
||||
|
||||
/**
|
||||
* Maintains several stateflows for each step in processing PeopleLists
|
||||
|
||||
@@ -186,11 +186,11 @@ class AccountFollowsLoaderSubAssembler(
|
||||
}
|
||||
|
||||
// removes accounts that are not being subscribed anymore.
|
||||
accountUpdatesJobMap.forEach {
|
||||
if (it.key !in uniqueSubscribedAccounts.keys) {
|
||||
endWatcher(it.key)
|
||||
}
|
||||
}
|
||||
// Cancel watchers for accounts no longer observed using a snapshot to avoid CME
|
||||
accountUpdatesJobMap.keys
|
||||
.toList()
|
||||
.filter { it !in uniqueSubscribedAccounts.keys }
|
||||
.forEach { endWatcher(it) }
|
||||
}
|
||||
|
||||
private val accountUpdatesJobMap = mutableMapOf<User, Job>()
|
||||
|
||||
@@ -90,19 +90,30 @@ class UserReportsSubAssembler(
|
||||
users: Iterable<User>,
|
||||
eoseCache: EOSEAccountFast<User>,
|
||||
inRelays: Set<NormalizedRelayUrl>,
|
||||
): Collection<List<User>> =
|
||||
users
|
||||
.groupBy {
|
||||
eoseCache
|
||||
.since(it)
|
||||
?.keys
|
||||
?.intersect(inRelays)
|
||||
?.hashCode()
|
||||
): Collection<List<User>> {
|
||||
if (users.none()) return emptyList()
|
||||
|
||||
val relaySnapshot = inRelays.toSet()
|
||||
|
||||
return users
|
||||
.groupBy { user ->
|
||||
val relaysForUser = eoseCache.sinceRelaySet(user)
|
||||
if (relaysForUser.isNullOrEmpty() || relaySnapshot.isEmpty()) {
|
||||
null
|
||||
} else {
|
||||
val intersection = relaysForUser.filter { it in relaySnapshot }.sorted()
|
||||
if (intersection.isEmpty()) {
|
||||
null
|
||||
} else {
|
||||
intersection.hashCode()
|
||||
}
|
||||
}
|
||||
}.values
|
||||
.map {
|
||||
// important to keep in order otherwise the Relay thinks the filter has changed and we REQ again
|
||||
it.sortedBy { it.pubkeyHex }
|
||||
}
|
||||
}
|
||||
|
||||
fun findMinimumEOSEsForUsers(
|
||||
users: List<User>,
|
||||
|
||||
@@ -125,36 +125,51 @@ class EOSEAccountFast<T : Any>(
|
||||
cacheSize: Int = 20,
|
||||
) {
|
||||
private val users: LruCache<T, EOSERelayList> = LruCache<T, EOSERelayList>(cacheSize)
|
||||
private val lock = Any()
|
||||
|
||||
fun addOrUpdate(
|
||||
user: T,
|
||||
relayUrl: NormalizedRelayUrl,
|
||||
time: Long,
|
||||
) {
|
||||
val relayList = users[user]
|
||||
if (relayList == null) {
|
||||
val newList = EOSERelayList()
|
||||
users.put(user, newList)
|
||||
synchronized(lock) {
|
||||
val relayList = users[user]
|
||||
if (relayList == null) {
|
||||
val newList = EOSERelayList()
|
||||
users.put(user, newList)
|
||||
|
||||
newList.addOrUpdate(relayUrl, time)
|
||||
} else {
|
||||
relayList.addOrUpdate(relayUrl, time)
|
||||
newList.addOrUpdate(relayUrl, time)
|
||||
} else {
|
||||
relayList.addOrUpdate(relayUrl, time)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeEveryoneBut(list: Set<T>) {
|
||||
users.snapshot().forEach {
|
||||
if (it.key !in list) {
|
||||
users.remove(it.key)
|
||||
synchronized(lock) {
|
||||
users.snapshot().forEach {
|
||||
if (it.key !in list) {
|
||||
users.remove(it.key)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun removeDataFor(user: T) {
|
||||
users.remove(user)
|
||||
synchronized(lock) {
|
||||
users.remove(user)
|
||||
}
|
||||
}
|
||||
|
||||
fun since(key: T) = users[key]?.relayList
|
||||
fun since(key: T): SincePerRelayMap? =
|
||||
synchronized(lock) {
|
||||
users[key]?.relayList?.toMutableMap()
|
||||
}
|
||||
|
||||
fun sinceRelaySet(key: T): Set<NormalizedRelayUrl>? =
|
||||
synchronized(lock) {
|
||||
users[key]?.relayList?.keys?.toSet()
|
||||
}
|
||||
|
||||
fun newEose(
|
||||
user: T,
|
||||
|
||||
@@ -34,7 +34,6 @@ import com.vitorpamplona.amethyst.R
|
||||
import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.account.observeAccountIsHiddenUser
|
||||
import com.vitorpamplona.amethyst.service.relayClient.reqCommand.user.observeUserIsFollowing
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.EmptyNav.nav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.Route
|
||||
import com.vitorpamplona.amethyst.ui.navigation.routes.routeFor
|
||||
|
||||
@@ -43,7 +43,6 @@ import com.vitorpamplona.amethyst.model.User
|
||||
import com.vitorpamplona.amethyst.ui.navigation.navs.INav
|
||||
import com.vitorpamplona.amethyst.ui.note.UserComposeNoAction
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.lists.list.PeopleListItem
|
||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||
import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
||||
import com.vitorpamplona.amethyst.ui.theme.HalfHalfHorzModifier
|
||||
|
||||
@@ -28,7 +28,6 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.outlined.Groups
|
||||
import androidx.compose.material.icons.outlined.Lock
|
||||
|
||||
Reference in New Issue
Block a user