-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathServiceQueue.kt
More file actions
65 lines (58 loc) · 2.14 KB
/
Copy pathServiceQueue.kt
File metadata and controls
65 lines (58 loc) · 2.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package to.bitkit.async
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExecutorCoroutineDispatcher
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.asCoroutineDispatcher
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import to.bitkit.ext.callerName
import to.bitkit.utils.AppError
import to.bitkit.utils.Logger
import to.bitkit.utils.measured
import java.util.concurrent.Executors
import java.util.concurrent.ThreadFactory
import kotlin.coroutines.CoroutineContext
enum class ServiceQueue {
LDK, CORE, FOREX, LOG, MIGRATION;
private val scope by lazy { CoroutineScope(newSingleThreadDispatcher(name) + SupervisorJob()) }
fun <T> blocking(
coroutineContext: CoroutineContext = scope.coroutineContext,
functionName: String = Thread.currentThread().callerName,
block: suspend CoroutineScope.() -> T,
): T {
return runBlocking(coroutineContext) {
try {
measured(label = functionName, context = TAG) {
block()
}
} catch (e: Exception) {
Logger.error("ServiceQueue.$name error", e)
throw AppError(e)
}
}
}
suspend fun <T> background(
coroutineContext: CoroutineContext = scope.coroutineContext,
functionName: String = Thread.currentThread().callerName,
block: suspend CoroutineScope.() -> T,
): T {
return withContext(coroutineContext) {
try {
measured(label = functionName, context = TAG) {
block()
}
} catch (e: Exception) {
Logger.error("ServiceQueue.$name error", e)
throw AppError(e)
}
}
}
companion object {
private const val TAG = "ServiceQueue"
}
}
fun newSingleThreadDispatcher(id: String): ExecutorCoroutineDispatcher {
val name = "$id-queue".lowercase()
val threadFactory = ThreadFactory { Thread(it, name).apply { priority = Thread.NORM_PRIORITY - 1 } }
return Executors.newSingleThreadExecutor(threadFactory).asCoroutineDispatcher()
}