Make comment profile fetching concurrent across all profiles and not sequential

This commit is contained in:
Aidan 2024-10-23 12:19:46 -07:00
parent c046619b8b
commit f25f27348b

View File

@ -44,9 +44,11 @@ import com.futo.polycentric.core.toBase64
import com.futo.polycentric.core.toURLInfoSystemLinkUrl import com.futo.polycentric.core.toURLInfoSystemLinkUrl
import com.google.protobuf.ByteString import com.google.protobuf.ByteString
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.Deferred import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import userpackage.Protocol import userpackage.Protocol
import userpackage.Protocol.Reference import userpackage.Protocol.Reference
@ -510,67 +512,88 @@ class StatePolycentric {
}; };
} }
private suspend fun mapQueryReferences(contextUrl: String, response: Protocol.QueryReferencesResponse): List<PolycentricPlatformComment> { private suspend fun mapQueryReferences(contextUrl: String, response: Protocol.QueryReferencesResponse): List<PolycentricPlatformComment> = coroutineScope {
return response.itemsList.mapNotNull { response.itemsList.map { item ->
val sev = SignedEvent.fromProto(it.event); async {
val ev = sev.event; val sev = SignedEvent.fromProto(item.event)
if (ev.contentType != ContentType.POST.value) { val ev = sev.event
return@mapNotNull null; if (ev.contentType != ContentType.POST.value) {
} return@async null
}
try { try {
val post = Protocol.Post.parseFrom(ev.content); val post = Protocol.Post.parseFrom(ev.content)
val likes = it.countsList[0]; val likes = item.countsList.getOrNull(0)
val dislikes = it.countsList[1]; val dislikes = item.countsList.getOrNull(1)
val replies = it.countsList[2]; val replies = item.countsList.getOrNull(2)
val profileEvents = ApiMethods.getQueryLatest( val profileEvents = ApiMethods.getQueryLatest(
PolycentricCache.SERVER, PolycentricCache.SERVER,
ev.system.toProto(), ev.system.toProto(),
listOf( listOf(
ContentType.AVATAR.value, ContentType.AVATAR.value,
ContentType.USERNAME.value ContentType.USERNAME.value
) )
).eventsList.map { e -> SignedEvent.fromProto(e) }.groupBy { e -> e.event.contentType } ).eventsList.map { e -> SignedEvent.fromProto(e) }.groupBy { e -> e.event.contentType }
.map { (_, events) -> events.maxBy { x -> x.event.unixMilliseconds ?: 0 } }; .map { (_, events) -> events.maxBy { x -> x.event.unixMilliseconds ?: 0 } };
val nameEvent = profileEvents.firstOrNull { e -> e.event.contentType == ContentType.USERNAME.value }; val nameEvent = profileEvents.firstOrNull { e -> e.event.contentType == ContentType.USERNAME.value };
val avatarEvent = profileEvents.firstOrNull { e -> e.event.contentType == ContentType.AVATAR.value }; val avatarEvent = profileEvents.firstOrNull { e -> e.event.contentType == ContentType.AVATAR.value };
val imageBundle = if (avatarEvent != null) { val imageBundle = if (avatarEvent != null) {
val lwwElementValue = avatarEvent.event.lwwElement?.value; val lwwElementValue = avatarEvent.event.lwwElement?.value;
if (lwwElementValue != null) { if (lwwElementValue != null) {
Protocol.ImageBundle.parseFrom(lwwElementValue) Protocol.ImageBundle.parseFrom(lwwElementValue)
} else {
null
}
} else { } else {
null null
} }
} else {
val unixMilliseconds = ev.unixMilliseconds
//TODO: Don't use single hardcoded server here
val systemLinkUrl = ev.system.systemToURLInfoSystemLinkUrl(listOf(PolycentricCache.SERVER))
val dp_25 = 25.dp(StateApp.instance.context.resources)
PolycentricPlatformComment(
contextUrl = contextUrl,
author = PlatformAuthorLink(
id = PlatformID(
"polycentric",
systemLinkUrl,
null,
ClaimType.POLYCENTRIC.value.toInt()
),
name = nameEvent?.event?.lwwElement?.value?.decodeToString() ?: "Unknown",
url = systemLinkUrl,
thumbnail = imageBundle?.selectBestImage(dp_25 * dp_25)?.let { img ->
img.toURLInfoSystemLinkUrl(
ev.system.toProto(),
img.process,
listOf(PolycentricCache.SERVER)
)
},
subscribers = null
),
msg = if (post.content.length > PolycentricPlatformComment.MAX_COMMENT_SIZE) {
post.content.substring(0, PolycentricPlatformComment.MAX_COMMENT_SIZE)
} else {
post.content
},
rating = RatingLikeDislikes(likes ?: 0, dislikes ?: 0),
date = unixMilliseconds?.let {
Instant.ofEpochMilli(it).atOffset(ZoneOffset.UTC)
} ?: OffsetDateTime.MIN,
replyCount = replies?.toInt() ?: 0,
eventPointer = sev.toPointer(),
parentReference = sev.event.references.getOrNull(0)
)
} catch (e: Throwable) {
null null
} }
val unixMilliseconds = ev.unixMilliseconds
//TODO: Don't use single hardcoded sderver here
val systemLinkUrl = ev.system.systemToURLInfoSystemLinkUrl(listOf(PolycentricCache.SERVER));
val dp_25 = 25.dp(StateApp.instance.context.resources)
return@mapNotNull PolycentricPlatformComment(
contextUrl = contextUrl,
author = PlatformAuthorLink(
id = PlatformID("polycentric", systemLinkUrl, null, ClaimType.POLYCENTRIC.value.toInt()),
name = nameEvent?.event?.lwwElement?.value?.decodeToString() ?: "Unknown",
url = systemLinkUrl,
thumbnail = imageBundle?.selectBestImage(dp_25 * dp_25)?.let { img -> img.toURLInfoSystemLinkUrl(ev.system.toProto(), img.process, listOf(PolycentricCache.SERVER)) },
subscribers = null
),
msg = if (post.content.count() > PolycentricPlatformComment.MAX_COMMENT_SIZE) post.content.substring(0, PolycentricPlatformComment.MAX_COMMENT_SIZE) else post.content,
rating = RatingLikeDislikes(likes, dislikes),
date = if (unixMilliseconds != null) Instant.ofEpochMilli(unixMilliseconds).atOffset(ZoneOffset.UTC) else OffsetDateTime.MIN,
replyCount = replies.toInt(),
eventPointer = sev.toPointer(),
parentReference = sev.event.references.getOrNull(0)
);
} catch (e: Throwable) {
return@mapNotNull null;
} }
}; }.awaitAll().filterNotNull()
} }
companion object { companion object {