From 9002606917996236517954e3576ce961196f0aa1 Mon Sep 17 00:00:00 2001 From: Anton Chekulaev Date: Thu, 17 Dec 2020 16:56:19 +1100 Subject: [PATCH] Tweak snode path error handling Changes from f4281963882 (service repo) --- .../session/libsignal/service/loki/api/SwarmAPI.kt | 9 +++++++-- .../loki/api/onionrequests/OnionRequestAPI.kt | 12 ++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt index 43a10108a8..0fd7d1379b 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt @@ -10,6 +10,7 @@ import org.session.libsignal.service.loki.api.utilities.HTTP import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.getRandomElement import org.session.libsignal.service.loki.utilities.prettifiedDescription +import org.session.libsignal.service.loki.utilities.retryIfNeeded import java.security.SecureRandom import java.util.* @@ -27,11 +28,12 @@ class SwarmAPI private constructor(private val database: LokiAPIDatabaseProtocol private val minimumSnodePoolCount = 64 private val minimumSwarmSnodeCount = 2 private val targetSwarmSnodeCount = 2 + private val maxRetryCount = 6 /** * A snode is kicked out of a swarm and/or the snode pool if it fails this many times. */ - internal val snodeFailureThreshold = 4 + internal val snodeFailureThreshold = 2 // endregion // region Initialization @@ -115,7 +117,10 @@ class SwarmAPI private constructor(private val database: LokiAPIDatabaseProtocol } else { val parameters = mapOf( "pubKey" to publicKey ) return getRandomSnode().bind { - SnodeAPI.shared.invoke(Snode.Method.GetSwarm, it, publicKey, parameters) + retryIfNeeded(maxRetryCount) { + SnodeAPI.shared.invoke(Snode.Method.GetSwarm, it, publicKey, parameters) + } + }.map(SnodeAPI.sharedContext) { parseSnodes(it).toSet() }.success { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt index b5e04e6750..acc783be7b 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt @@ -44,11 +44,11 @@ public object OnionRequestAPI { /** * The number of times a path can fail before it's replaced. */ - private val pathFailureThreshold = 2 + private val pathFailureThreshold = 1 /** * The number of times a snode can fail before it's replaced. */ - private val snodeFailureThreshold = 2 + private val snodeFailureThreshold = 1 /** * The number of paths to maintain. */ @@ -293,10 +293,10 @@ public object OnionRequestAPI { */ private fun sendOnionRequest(destination: Destination, payload: Map<*, *>, isJSONRequired: Boolean = true): Promise, Exception> { val deferred = deferred, Exception>() - lateinit var guardSnode: Snode + var guardSnode: Snode? = null buildOnionForDestination(payload, destination).success { result -> guardSnode = result.guardSnode - val url = "${guardSnode.address}:${guardSnode.port}/onion_req/v2" + val url = "${guardSnode!!.address}:${guardSnode!!.port}/onion_req/v2" val finalEncryptionResult = result.finalEncryptionResult val onion = finalEncryptionResult.ciphertext if (destination is Destination.Server && onion.count().toDouble() > 0.75 * FileServerAPI.maxFileSize.toDouble()) { @@ -365,14 +365,14 @@ public object OnionRequestAPI { } val promise = deferred.promise promise.fail { exception -> - val path = paths.firstOrNull { it.contains(guardSnode) } + val path = if (guardSnode != null) paths.firstOrNull { it.contains(guardSnode!!) } else null if (exception is HTTP.HTTPRequestFailedException) { fun handleUnspecificError() { if (path == null) { return } var pathFailureCount = OnionRequestAPI.pathFailureCount[path] ?: 0 pathFailureCount += 1 if (pathFailureCount >= pathFailureThreshold) { - dropGuardSnode(guardSnode) + dropGuardSnode(guardSnode!!) path.forEach { snode -> @Suppress("ThrowableNotThrown") SnodeAPI.shared.handleSnodeError(exception.statusCode, exception.json, snode, null) // Intentionally don't throw