From 966b8e0d7f744838dc176ee344703736ecb1cd71 Mon Sep 17 00:00:00 2001 From: SessionHero01 <180888785+SessionHero01@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:51:28 +1100 Subject: [PATCH] Close group poller issue --- .../pollers/ClosedGroupPoller.kt | 4 +-- .../org/session/libsession/snode/SnodeAPI.kt | 35 ++++++++++++++++++- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt index f49560b58e..1fad1d48ae 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt @@ -59,12 +59,12 @@ class ClosedGroupPoller( job = scope.launch(executor) { while (isActive) { try { - val swarmNodes = SnodeAPI.getSwarm(closedGroupSessionId.hexString).await().toMutableSet() + val swarmNodes = SnodeAPI.fetchSwarmNodes(closedGroupSessionId.hexString).toMutableSet() var currentSnode: Snode? = null while (isActive) { if (currentSnode == null) { - check(swarmNodes.isNotEmpty()) { "No swarm nodes found" } + check(swarmNodes.isNotEmpty()) { "No more swarm nodes found" } Log.d(TAG, "No current snode, getting a new one. Remaining in pool = ${swarmNodes.size - 1}") currentSnode = swarmNodes.random() swarmNodes.remove(currentSnode) diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index 029438b788..82a6f988e1 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -312,6 +312,23 @@ object SnodeAPI { database.setSwarm(publicKey, it) } + /** + * Fetch swarm nodes for the specific public key. + * + * Note: this differs from [getSwarm] in that it doesn't store the swarm nodes in the database. + * This always fetches from network. + */ + suspend fun fetchSwarmNodes(publicKey: String): List { + val randomNode = getRandomSnode().await() + val response = invoke( + method = Snode.Method.GetSwarm, + snode = randomNode, parameters = buildMap { this["pubKey"] = publicKey }, + publicKey = publicKey + ).await() + + return parseSnodes(response) + } + /** * Build parameters required to call authenticated storage API. @@ -706,7 +723,23 @@ object SnodeAPI { parameters = mapOf("requests" to requests), responseClass = BatchResponse::class.java, publicKey = publicKey - ) + ).also { resp -> + // If there's a unsuccessful response, go through specific logic to handle + // potential snode errors. + val firstError = resp.results.firstOrNull { !it.isSuccessful } + if (firstError != null) { + handleSnodeError( + statusCode = firstError.code, + json = if (firstError.body.isObject) { + JsonUtil.fromJson(firstError.body, Map::class.java) + } else { + null + }, + snode = snode, + publicKey = publicKey + ) + } + } } fun getExpiries(