Remove the use of executor in ThreadUtils

This commit is contained in:
fanchao 2024-06-24 14:05:06 +10:00
parent 1619277b4f
commit 0547dde554
2 changed files with 7 additions and 26 deletions

View File

@ -1,5 +1,7 @@
package org.thoughtcrime.securesms package org.thoughtcrime.securesms
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.asExecutor
import nl.komponents.kovenant.Kovenant import nl.komponents.kovenant.Kovenant
import nl.komponents.kovenant.jvm.asDispatcher import nl.komponents.kovenant.jvm.asDispatcher
import org.session.libsignal.utilities.Log import org.session.libsignal.utilities.Log
@ -11,7 +13,7 @@ object AppContext {
fun configureKovenant() { fun configureKovenant() {
Kovenant.context { Kovenant.context {
callbackContext.dispatcher = Executors.newSingleThreadExecutor().asDispatcher() callbackContext.dispatcher = Executors.newSingleThreadExecutor().asDispatcher()
workerContext.dispatcher = ThreadUtils.executorPool.asDispatcher() workerContext.dispatcher = Dispatchers.IO.asExecutor().asDispatcher()
multipleCompletion = { v1, v2 -> multipleCompletion = { v1, v2 ->
Log.d("Loki", "Promise resolved more than once (first with $v1, then with $v2); ignoring $v2.") Log.d("Loki", "Promise resolved more than once (first with $v1, then with $v2); ignoring $v2.")
} }

View File

@ -1,11 +1,13 @@
package org.session.libsignal.utilities package org.session.libsignal.utilities
import android.os.Process import android.os.Process
import kotlinx.coroutines.Dispatchers
import java.util.concurrent.ExecutorService import java.util.concurrent.ExecutorService
import java.util.concurrent.LinkedBlockingQueue import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.SynchronousQueue import java.util.concurrent.SynchronousQueue
import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import kotlin.coroutines.EmptyCoroutineContext
object ThreadUtils { object ThreadUtils {
@ -13,39 +15,16 @@ object ThreadUtils {
const val PRIORITY_IMPORTANT_BACKGROUND_THREAD = Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE const val PRIORITY_IMPORTANT_BACKGROUND_THREAD = Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE
// Paraphrased from: https://www.baeldung.com/kotlin/create-thread-pool
// "A cached thread pool such as one created via:
// `val executorPool: ExecutorService = Executors.newCachedThreadPool()`
// will utilize resources according to the requirements of submitted tasks. It will try to reuse
// existing threads for submitted tasks but will create as many threads as it needs if new tasks
// keep pouring in (with a memory usage of at least 1MB per created thread). These threads will
// live for up to 60 seconds of idle time before terminating by default. As such, it presents a
// very sharp tool that doesn't include any backpressure mechanism - and a sudden peak in load
// can bring the system down with an OutOfMemory error. We can achieve a similar effect but with
// better control by creating a ThreadPoolExecutor manually."
private val corePoolSize = Runtime.getRuntime().availableProcessors() // Default thread pool size is our CPU core count
private val maxPoolSize = corePoolSize * 4 // Allow a maximum pool size of up to 4 threads per core
private val keepAliveTimeSecs = 100L // How long to keep idle threads in the pool before they are terminated
private val workQueue = SynchronousQueue<Runnable>()
val executorPool: ExecutorService = ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTimeSecs, TimeUnit.SECONDS, workQueue)
// Note: To see how many threads are running in our app at any given time we can use: // Note: To see how many threads are running in our app at any given time we can use:
// val threadCount = getAllStackTraces().size // val threadCount = getAllStackTraces().size
@JvmStatic @JvmStatic
fun queue(target: Runnable) { fun queue(target: Runnable) {
executorPool.execute { queue(target::run)
try {
target.run()
} catch (e: Exception) {
Log.e(TAG, e)
}
}
} }
fun queue(target: () -> Unit) { fun queue(target: () -> Unit) {
executorPool.execute { Dispatchers.IO.dispatch(EmptyCoroutineContext) {
try { try {
target() target()
} catch (e: Exception) { } catch (e: Exception) {