Getting rid of .get call on promise

This commit is contained in:
SessionHero01
2024-10-02 11:25:37 +10:00
parent 45a66d0eea
commit 3faae5ddbe
27 changed files with 363 additions and 344 deletions

View File

@@ -1,10 +1,14 @@
package org.session.libsignal.utilities
import android.util.Log
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.Call
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
import org.session.libsignal.utilities.Util.SECURE_RANDOM
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
@@ -81,14 +85,14 @@ object HTTP {
/**
* Sync. Don't call from the main thread.
*/
fun execute(verb: Verb, url: String, timeout: Long = HTTP.timeout, useSeedNodeConnection: Boolean = false): ByteArray {
suspend fun execute(verb: Verb, url: String, timeout: Long = HTTP.timeout, useSeedNodeConnection: Boolean = false): ByteArray {
return execute(verb = verb, url = url, body = null, timeout = timeout, useSeedNodeConnection = useSeedNodeConnection)
}
/**
* Sync. Don't call from the main thread.
*/
fun execute(verb: Verb, url: String, parameters: Map<String, Any>?, timeout: Long = HTTP.timeout, useSeedNodeConnection: Boolean = false): ByteArray {
suspend fun execute(verb: Verb, url: String, parameters: Map<String, Any>?, timeout: Long = HTTP.timeout, useSeedNodeConnection: Boolean = false): ByteArray {
return if (parameters != null) {
val body = JsonUtil.toJson(parameters).toByteArray()
execute(verb = verb, url = url, body = body, timeout = timeout, useSeedNodeConnection = useSeedNodeConnection)
@@ -100,7 +104,7 @@ object HTTP {
/**
* Sync. Don't call from the main thread.
*/
fun execute(verb: Verb, url: String, body: ByteArray?, timeout: Long = HTTP.timeout, useSeedNodeConnection: Boolean = false): ByteArray {
suspend fun execute(verb: Verb, url: String, body: ByteArray?, timeout: Long = HTTP.timeout, useSeedNodeConnection: Boolean = false): ByteArray {
val request = Request.Builder().url(url)
.removeHeader("User-Agent").addHeader("User-Agent", "WhatsApp") // Set a fake value
.removeHeader("Accept-Language").addHeader("Accept-Language", "en-us") // Set a fake value
@@ -125,7 +129,7 @@ object HTTP {
}
useSeedNodeConnection -> seedNodeConnection
else -> defaultConnection
}.newCall(request.build()).execute().use { response ->
}.newCall(request.build()).await().use { response ->
when (val statusCode = response.code) {
200 -> response.body!!.bytes()
else -> {
@@ -143,4 +147,13 @@ object HTTP {
throw HTTPRequestFailedException(0, null, "HTTP request failed due to: ${exception.message}")
}
}
@Suppress("OPT_IN_USAGE")
private val httpCallDispatcher = Dispatchers.IO.limitedParallelism(3)
private suspend fun Call.await(): Response {
return withContext(httpCallDispatcher) {
execute()
}
}
}

View File

@@ -4,19 +4,9 @@ package org.session.libsignal.utilities
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred
import nl.komponents.kovenant.functional.map
import nl.komponents.kovenant.task
import java.util.concurrent.TimeoutException
fun emptyPromise() = EMPTY_PROMISE
private val EMPTY_PROMISE: Promise<*, java.lang.Exception> = task {}
fun emptyPromise() = Promise.of(Unit)
fun <V, E : Throwable> Promise<V, E>.get(defaultValue: V): V {
return try {
get()
} catch (e: Exception) {
defaultValue
}
}
fun <V, E : Throwable> Promise<V, E>.recover(callback: (exception: E) -> V): Promise<V, E> {
val deferred = deferred<V, E>()
@@ -33,33 +23,6 @@ fun <V, E : Throwable> Promise<V, E>.recover(callback: (exception: E) -> V): Pro
return deferred.promise
}
fun <V, E> Promise<V, E>.successBackground(callback: (value: V) -> Unit): Promise<V, E> {
ThreadUtils.queue {
try {
callback(get())
} catch (e: Exception) {
Log.d("Loki", "Failed to execute task in background: ${e.message}.")
}
}
return this
}
fun <V> Promise<V, Exception>.timeout(millis: Long): Promise<V, Exception> {
if (this.isDone()) { return this; }
val deferred = deferred<V, Exception>()
ThreadUtils.queue {
Thread.sleep(millis)
if (!deferred.promise.isDone()) {
deferred.reject(TimeoutException("Promise timed out."))
}
}
this.success {
if (!deferred.promise.isDone()) { deferred.resolve(it) }
}.fail {
if (!deferred.promise.isDone()) { deferred.reject(it) }
}
return deferred.promise
}
infix fun <V, E: Exception> Promise<V, E>.sideEffect(
callback: (value: V) -> Unit

View File

@@ -14,16 +14,10 @@ object ThreadUtils {
const val PRIORITY_IMPORTANT_BACKGROUND_THREAD = Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE
// Note: To see how many threads are running in our app at any given time we can use:
// val threadCount = getAllStackTraces().size
@Deprecated("Use a proper coroutine context/dispatcher instead, so it's clearer what priority you want the work to be done")
@JvmStatic
fun queue(target: Runnable) {
queue(target::run)
}
fun queue(target: () -> Unit) {
Dispatchers.IO.dispatch(EmptyCoroutineContext) {
Dispatchers.Default.dispatch(EmptyCoroutineContext) {
try {
target()
} catch (e: Exception) {