marcinmoskala
02/16/2024, 10:37 AMimport io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlin.time.measureTime
val client = HttpClient(CIO) {
engine {
endpoint.connectTimeout = 100_000
}
}
suspend fun getDelayedResponse(seconds: Int, a: Int) {
client.get("<https://api.kt.academy/delay>") {
parameter("delay", seconds)
parameter("a", a)
}
}
suspend fun main() = measureTime {
runBlocking {
repeat(1000) {
launch {
getDelayedResponse(2000, it)
}
}
delay(1000)
Thread.getAllStackTraces().keys.filter { it.isAlive }.map { it.name }.let {
println("Active threads: ${it.size}")
println(it)
}
}
}.let { println("Took ${it.inWholeSeconds}") }
It shows, that there are 89 active threads, 81 are DefaultDispatcher-worker-X, and the whole process takes 23 seconds (what is consistent with 81 active requests). Does it mean that CIO also requires a thread per active request?Aleksei Tirman [JB]
02/16/2024, 12:39 PMmarcinmoskala
02/16/2024, 1:08 PMe5l
02/20/2024, 8:03 AMmarcinmoskala
02/23/2024, 9:36 AMe5l
02/23/2024, 9:39 AMmarcinmoskala
02/23/2024, 9:55 AMlimitedParallelism
. Otherwise it is limited, and it has one limit for the whole app.e5l
02/23/2024, 9:59 AMmarcinmoskala
03/04/2024, 9:09 AMimport io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.util.concurrent.atomic.AtomicInteger
import kotlin.time.measureTime
val client = HttpClient(CIO) {
engine {
maxConnectionsCount = 1000
endpoint.connectTimeout = 100_000
requestTimeout = 100_000
}
}
suspend fun getDelayedResponse(seconds: Int, a: Int) {
client.get("<https://api.kt.academy/delay>") {
parameter("delay", seconds)
parameter("a", a)
}
}
suspend fun main() = measureTime {
runBlocking {
val finished = AtomicInteger(0)
repeat(1000) {
launch {
getDelayedResponse(3000, it)
finished.incrementAndGet()
}
}
delay(1000)
printActiveThreads()
repeat(50) {
launch(Dispatchers.IO) {
Thread.sleep(1000)
}
}
delay(100)
printActiveThreads()
println(finished.get())
}
}.let { println("Took ${it.inWholeSeconds}") }
fun printActiveThreads() {
Thread.getAllStackTraces().keys.filter { it.isAlive }.map { it.name }.let {
println("Active threads: ${it.size}")
println(it)
}
}
/*
Active threads: 93
[DefaultDispatcher-worker-16, DefaultDispatcher-worker-81, DefaultDispatcher-worker-38, DefaultDispatcher-worker-35, DefaultDispatcher-worker-58, DefaultDispatcher-worker-85, DefaultDispatcher-worker-13, DefaultDispatcher-worker-4, DefaultDispatcher-worker-28, DefaultDispatcher-worker-56, DefaultDispatcher-worker-57, DefaultDispatcher-worker-77, DefaultDispatcher-worker-73, DefaultDispatcher-worker-75, DefaultDispatcher-worker-61, DefaultDispatcher-worker-18, DefaultDispatcher-worker-41, Signal Dispatcher, DefaultDispatcher-worker-45, DefaultDispatcher-worker-36, DefaultDispatcher-worker-49, Monitor Ctrl-Break, DefaultDispatcher-worker-47, DefaultDispatcher-worker-62, DefaultDispatcher-worker-6, DefaultDispatcher-worker-29, DefaultDispatcher-worker-30, Reference Handler, DefaultDispatcher-worker-50, DefaultDispatcher-worker-68, DefaultDispatcher-worker-15, DefaultDispatcher-worker-20, DefaultDispatcher-worker-43, DefaultDispatcher-worker-65, DefaultDispatcher-worker-54, DefaultDispatcher-worker-37, DefaultDispatcher-worker-19, Common-Cleaner, DefaultDispatcher-worker-52, DefaultDispatcher-worker-10, DefaultDispatcher-worker-51, DefaultDispatcher-worker-70, DefaultDispatcher-worker-1, DefaultDispatcher-worker-25, DefaultDispatcher-worker-33, DefaultDispatcher-worker-14, DefaultDispatcher-worker-78, DefaultDispatcher-worker-44, DefaultDispatcher-worker-2, DefaultDispatcher-worker-69, DefaultDispatcher-worker-8, DefaultDispatcher-worker-40, DefaultDispatcher-worker-60, DefaultDispatcher-worker-53, DefaultDispatcher-worker-42, DefaultDispatcher-worker-74, DefaultDispatcher-worker-83, Finalizer, DefaultDispatcher-worker-48, DefaultDispatcher-worker-24, DefaultDispatcher-worker-21, DefaultDispatcher-worker-9, DefaultDispatcher-worker-17, DefaultDispatcher-worker-64, DefaultDispatcher-worker-72, DefaultDispatcher-worker-23, DefaultDispatcher-worker-3, DefaultDispatcher-worker-84, DefaultDispatcher-worker-71, DefaultDispatcher-worker-31, DefaultDispatcher-worker-63, DefaultDispatcher-worker-79, DefaultDispatcher-worker-7, DefaultDispatcher-worker-26, DefaultDispatcher-worker-46, DefaultDispatcher-worker-22, main, DefaultDispatcher-worker-34, DefaultDispatcher-worker-80, kotlinx.coroutines.DefaultExecutor, DefaultDispatcher-worker-55, DefaultDispatcher-worker-39, DefaultDispatcher-worker-5, DefaultDispatcher-worker-66, DefaultDispatcher-worker-11, DefaultDispatcher-worker-59, DefaultDispatcher-worker-76, DefaultDispatcher-worker-82, DefaultDispatcher-worker-32, Notification Thread, DefaultDispatcher-worker-27, DefaultDispatcher-worker-12, DefaultDispatcher-worker-67]
Active threads: 93
[DefaultDispatcher-worker-16, DefaultDispatcher-worker-81, DefaultDispatcher-worker-38, DefaultDispatcher-worker-35, DefaultDispatcher-worker-58, DefaultDispatcher-worker-85, DefaultDispatcher-worker-13, DefaultDispatcher-worker-4, DefaultDispatcher-worker-28, DefaultDispatcher-worker-56, DefaultDispatcher-worker-57, DefaultDispatcher-worker-77, DefaultDispatcher-worker-73, DefaultDispatcher-worker-75, DefaultDispatcher-worker-61, DefaultDispatcher-worker-18, DefaultDispatcher-worker-41, Signal Dispatcher, DefaultDispatcher-worker-45, DefaultDispatcher-worker-36, DefaultDispatcher-worker-49, Monitor Ctrl-Break, DefaultDispatcher-worker-47, DefaultDispatcher-worker-62, DefaultDispatcher-worker-6, DefaultDispatcher-worker-29, DefaultDispatcher-worker-30, Reference Handler, DefaultDispatcher-worker-50, DefaultDispatcher-worker-68, DefaultDispatcher-worker-15, DefaultDispatcher-worker-20, DefaultDispatcher-worker-43, DefaultDispatcher-worker-65, DefaultDispatcher-worker-54, DefaultDispatcher-worker-37, DefaultDispatcher-worker-19, Common-Cleaner, DefaultDispatcher-worker-52, DefaultDispatcher-worker-10, DefaultDispatcher-worker-51, DefaultDispatcher-worker-70, DefaultDispatcher-worker-1, DefaultDispatcher-worker-25, DefaultDispatcher-worker-33, DefaultDispatcher-worker-14, DefaultDispatcher-worker-78, DefaultDispatcher-worker-44, DefaultDispatcher-worker-2, DefaultDispatcher-worker-69, DefaultDispatcher-worker-8, DefaultDispatcher-worker-40, DefaultDispatcher-worker-60, DefaultDispatcher-worker-53, DefaultDispatcher-worker-42, DefaultDispatcher-worker-74, DefaultDispatcher-worker-83, Finalizer, DefaultDispatcher-worker-48, DefaultDispatcher-worker-24, DefaultDispatcher-worker-21, DefaultDispatcher-worker-9, DefaultDispatcher-worker-17, DefaultDispatcher-worker-64, DefaultDispatcher-worker-72, DefaultDispatcher-worker-23, DefaultDispatcher-worker-3, DefaultDispatcher-worker-84, DefaultDispatcher-worker-71, DefaultDispatcher-worker-31, DefaultDispatcher-worker-63, DefaultDispatcher-worker-79, DefaultDispatcher-worker-7, DefaultDispatcher-worker-26, DefaultDispatcher-worker-46, DefaultDispatcher-worker-22, main, DefaultDispatcher-worker-34, DefaultDispatcher-worker-80, kotlinx.coroutines.DefaultExecutor, DefaultDispatcher-worker-55, DefaultDispatcher-worker-39, DefaultDispatcher-worker-5, DefaultDispatcher-worker-66, DefaultDispatcher-worker-11, DefaultDispatcher-worker-59, DefaultDispatcher-worker-76, DefaultDispatcher-worker-82, DefaultDispatcher-worker-32, Notification Thread, DefaultDispatcher-worker-27, DefaultDispatcher-worker-12, DefaultDispatcher-worker-67]
0
*/
e5l
03/04/2024, 9:11 AMmarcinmoskala
03/04/2024, 9:16 AMActive threads: 87
[DefaultDispatcher-worker-16, DefaultDispatcher-worker-37, DefaultDispatcher-worker-35, DefaultDispatcher-worker-59, DefaultDispatcher-worker-13, DefaultDispatcher-worker-4, DefaultDispatcher-worker-28, DefaultDispatcher-worker-53, DefaultDispatcher-worker-57, DefaultDispatcher-worker-78, DefaultDispatcher-worker-73, DefaultDispatcher-worker-75, DefaultDispatcher-worker-61, DefaultDispatcher-worker-18, DefaultDispatcher-worker-42, Signal Dispatcher, DefaultDispatcher-worker-45, DefaultDispatcher-worker-36, DefaultDispatcher-worker-49, Monitor Ctrl-Break, DefaultDispatcher-worker-47, DefaultDispatcher-worker-62, DefaultDispatcher-worker-6, DefaultDispatcher-worker-29, DefaultDispatcher-worker-30, Reference Handler, DefaultDispatcher-worker-50, DefaultDispatcher-worker-69, DefaultDispatcher-worker-15, DefaultDispatcher-worker-20, DefaultDispatcher-worker-43, DefaultDispatcher-worker-65, DefaultDispatcher-worker-56, DefaultDispatcher-worker-38, DefaultDispatcher-worker-19, Common-Cleaner, DefaultDispatcher-worker-55, DefaultDispatcher-worker-10, DefaultDispatcher-worker-52, DefaultDispatcher-worker-70, DefaultDispatcher-worker-1, DefaultDispatcher-worker-25, DefaultDispatcher-worker-33, DefaultDispatcher-worker-14, DefaultDispatcher-worker-79, DefaultDispatcher-worker-44, DefaultDispatcher-worker-2, DefaultDispatcher-worker-68, DefaultDispatcher-worker-8, DefaultDispatcher-worker-39, DefaultDispatcher-worker-60, DefaultDispatcher-worker-51, DefaultDispatcher-worker-41, DefaultDispatcher-worker-74, Finalizer, DefaultDispatcher-worker-48, DefaultDispatcher-worker-24, DefaultDispatcher-worker-22, DefaultDispatcher-worker-9, DefaultDispatcher-worker-17, DefaultDispatcher-worker-64, DefaultDispatcher-worker-77, DefaultDispatcher-worker-23, DefaultDispatcher-worker-3, DefaultDispatcher-worker-71, DefaultDispatcher-worker-31, DefaultDispatcher-worker-63, DefaultDispatcher-worker-72, DefaultDispatcher-worker-7, DefaultDispatcher-worker-26, DefaultDispatcher-worker-46, kotlinx.coroutines.DefaultExecutor, main, DefaultDispatcher-worker-34, DefaultDispatcher-worker-21, DefaultDispatcher-worker-54, DefaultDispatcher-worker-40, DefaultDispatcher-worker-5, DefaultDispatcher-worker-66, DefaultDispatcher-worker-11, DefaultDispatcher-worker-58, DefaultDispatcher-worker-76, DefaultDispatcher-worker-32, Notification Thread, DefaultDispatcher-worker-27, DefaultDispatcher-worker-12, DefaultDispatcher-worker-67]
Active threads: 87
[DefaultDispatcher-worker-16, DefaultDispatcher-worker-37, DefaultDispatcher-worker-35, DefaultDispatcher-worker-59, DefaultDispatcher-worker-13, DefaultDispatcher-worker-4, DefaultDispatcher-worker-28, DefaultDispatcher-worker-53, DefaultDispatcher-worker-57, DefaultDispatcher-worker-78, DefaultDispatcher-worker-73, DefaultDispatcher-worker-75, DefaultDispatcher-worker-61, DefaultDispatcher-worker-18, DefaultDispatcher-worker-42, Signal Dispatcher, DefaultDispatcher-worker-45, DefaultDispatcher-worker-36, DefaultDispatcher-worker-49, Monitor Ctrl-Break, DefaultDispatcher-worker-47, DefaultDispatcher-worker-62, DefaultDispatcher-worker-6, DefaultDispatcher-worker-29, DefaultDispatcher-worker-30, Reference Handler, DefaultDispatcher-worker-50, DefaultDispatcher-worker-69, DefaultDispatcher-worker-15, DefaultDispatcher-worker-20, DefaultDispatcher-worker-43, DefaultDispatcher-worker-65, DefaultDispatcher-worker-56, DefaultDispatcher-worker-38, DefaultDispatcher-worker-19, Common-Cleaner, DefaultDispatcher-worker-55, DefaultDispatcher-worker-10, DefaultDispatcher-worker-52, DefaultDispatcher-worker-70, DefaultDispatcher-worker-1, DefaultDispatcher-worker-25, DefaultDispatcher-worker-33, DefaultDispatcher-worker-14, DefaultDispatcher-worker-79, DefaultDispatcher-worker-44, DefaultDispatcher-worker-2, DefaultDispatcher-worker-68, DefaultDispatcher-worker-8, DefaultDispatcher-worker-39, DefaultDispatcher-worker-60, DefaultDispatcher-worker-51, DefaultDispatcher-worker-41, DefaultDispatcher-worker-74, Finalizer, DefaultDispatcher-worker-48, DefaultDispatcher-worker-24, DefaultDispatcher-worker-22, DefaultDispatcher-worker-9, DefaultDispatcher-worker-17, DefaultDispatcher-worker-64, DefaultDispatcher-worker-77, DefaultDispatcher-worker-23, DefaultDispatcher-worker-3, DefaultDispatcher-worker-71, DefaultDispatcher-worker-31, DefaultDispatcher-worker-63, DefaultDispatcher-worker-72, DefaultDispatcher-worker-7, DefaultDispatcher-worker-26, DefaultDispatcher-worker-46, kotlinx.coroutines.DefaultExecutor, main, DefaultDispatcher-worker-34, DefaultDispatcher-worker-21, DefaultDispatcher-worker-54, DefaultDispatcher-worker-40, DefaultDispatcher-worker-5, DefaultDispatcher-worker-66, DefaultDispatcher-worker-11, DefaultDispatcher-worker-58, DefaultDispatcher-worker-76, DefaultDispatcher-worker-32, Notification Thread, DefaultDispatcher-worker-27, DefaultDispatcher-worker-12, DefaultDispatcher-worker-67]
e5l
03/04/2024, 9:16 AMmarcinmoskala
03/04/2024, 9:17 AMmarcinmoskala
03/04/2024, 9:17 AMmarcinmoskala
03/04/2024, 9:17 AMe5l
03/04/2024, 9:21 AMmarcinmoskala
03/04/2024, 9:25 AMimport io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.request.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.util.concurrent.atomic.AtomicInteger
import kotlin.time.measureTime
val client = HttpClient(CIO) {
engine {
maxConnectionsCount = 1000
endpoint.connectTimeout = 100_000
requestTimeout = 100_000
}
}
suspend fun getDelayedResponse(seconds: Int, a: Int) {
client.get("<https://api.kt.academy/delay>") {
parameter("delay", seconds)
parameter("a", a)
}
}
suspend fun main() = measureTime {
runBlocking {
val finished = AtomicInteger(0)
repeat(1000) {
delay(10)
launch {
getDelayedResponse(30000, it)
finished.incrementAndGet()
}
}
delay(10100)
printActiveThreads() // 50
repeat(50) {
launch(<http://Dispatchers.IO|Dispatchers.IO>) {
Thread.sleep(1000)
}
}
delay(100)
printActiveThreads()
println(finished.get())
}
}.let { println("Took ${it.inWholeSeconds}") }
fun printActiveThreads() {
Thread.getAllStackTraces().keys.filter { it.isAlive }.map { it.name }.let {
println("Active threads: ${it.size}")
println(it)
}
}
/*
Active threads: 68
[Signal Dispatcher, DefaultDispatcher-worker-25, DefaultDispatcher-worker-16, DefaultDispatcher-worker-39, main, DefaultDispatcher-worker-9, DefaultDispatcher-worker-37, DefaultDispatcher-worker-38, DefaultDispatcher-worker-49, DefaultDispatcher-worker-54, DefaultDispatcher-worker-57, DefaultDispatcher-worker-18, Monitor Ctrl-Break, DefaultDispatcher-worker-17, DefaultDispatcher-worker-26, DefaultDispatcher-worker-22, DefaultDispatcher-worker-30, DefaultDispatcher-worker-28, DefaultDispatcher-worker-43, DefaultDispatcher-worker-10, DefaultDispatcher-worker-11, DefaultDispatcher-worker-31, DefaultDispatcher-worker-56, Finalizer, DefaultDispatcher-worker-1, DefaultDispatcher-worker-24, DefaultDispatcher-worker-46, DefaultDispatcher-worker-36, DefaultDispatcher-worker-19, Notification Thread, DefaultDispatcher-worker-34, DefaultDispatcher-worker-32, DefaultDispatcher-worker-51, DefaultDispatcher-worker-6, DefaultDispatcher-worker-12, Reference Handler, DefaultDispatcher-worker-59, DefaultDispatcher-worker-42, DefaultDispatcher-worker-50, DefaultDispatcher-worker-20, DefaultDispatcher-worker-41, DefaultDispatcher-worker-33, DefaultDispatcher-worker-23, DefaultDispatcher-worker-55, DefaultDispatcher-worker-29, kotlinx.coroutines.DefaultExecutor, DefaultDispatcher-worker-3, Common-Cleaner, DefaultDispatcher-worker-45, DefaultDispatcher-worker-53, DefaultDispatcher-worker-5, DefaultDispatcher-worker-52, DefaultDispatcher-worker-14, DefaultDispatcher-worker-44, DefaultDispatcher-worker-60, DefaultDispatcher-worker-7, DefaultDispatcher-worker-27, DefaultDispatcher-worker-4, DefaultDispatcher-worker-15, DefaultDispatcher-worker-2, DefaultDispatcher-worker-35, DefaultDispatcher-worker-21, DefaultDispatcher-worker-47, DefaultDispatcher-worker-40, DefaultDispatcher-worker-58, DefaultDispatcher-worker-13, DefaultDispatcher-worker-8, DefaultDispatcher-worker-48]
Active threads: 69
[Signal Dispatcher, DefaultDispatcher-worker-61, DefaultDispatcher-worker-25, DefaultDispatcher-worker-16, DefaultDispatcher-worker-39, main, DefaultDispatcher-worker-9, DefaultDispatcher-worker-37, DefaultDispatcher-worker-38, DefaultDispatcher-worker-49, DefaultDispatcher-worker-54, DefaultDispatcher-worker-57, DefaultDispatcher-worker-18, Monitor Ctrl-Break, DefaultDispatcher-worker-17, DefaultDispatcher-worker-26, DefaultDispatcher-worker-22, DefaultDispatcher-worker-30, DefaultDispatcher-worker-28, DefaultDispatcher-worker-43, DefaultDispatcher-worker-10, DefaultDispatcher-worker-11, DefaultDispatcher-worker-31, DefaultDispatcher-worker-56, Finalizer, DefaultDispatcher-worker-1, DefaultDispatcher-worker-24, DefaultDispatcher-worker-46, DefaultDispatcher-worker-36, DefaultDispatcher-worker-19, Notification Thread, DefaultDispatcher-worker-34, DefaultDispatcher-worker-32, DefaultDispatcher-worker-51, DefaultDispatcher-worker-6, DefaultDispatcher-worker-12, Reference Handler, DefaultDispatcher-worker-59, DefaultDispatcher-worker-42, DefaultDispatcher-worker-50, DefaultDispatcher-worker-20, DefaultDispatcher-worker-41, DefaultDispatcher-worker-33, DefaultDispatcher-worker-23, DefaultDispatcher-worker-55, DefaultDispatcher-worker-29, kotlinx.coroutines.DefaultExecutor, DefaultDispatcher-worker-3, Common-Cleaner, DefaultDispatcher-worker-45, DefaultDispatcher-worker-53, DefaultDispatcher-worker-5, DefaultDispatcher-worker-52, DefaultDispatcher-worker-14, DefaultDispatcher-worker-44, DefaultDispatcher-worker-60, DefaultDispatcher-worker-7, DefaultDispatcher-worker-27, DefaultDispatcher-worker-4, DefaultDispatcher-worker-15, DefaultDispatcher-worker-2, DefaultDispatcher-worker-35, DefaultDispatcher-worker-21, DefaultDispatcher-worker-47, DefaultDispatcher-worker-40, DefaultDispatcher-worker-58, DefaultDispatcher-worker-13, DefaultDispatcher-worker-8, DefaultDispatcher-worker-48]
0
*/
marcinmoskala
03/04/2024, 9:29 AMmarcinmoskala
03/04/2024, 9:31 AMe5l
03/04/2024, 9:33 AMmarcinmoskala
03/04/2024, 9:36 AM"DefaultDispatcher-worker-2@1333" daemon prio=5 tid=0x13 nid=NA waiting
java.lang.Thread.State: WAITING
at jdk.internal.misc.Unsafe.park(Unsafe.java:-1)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:376)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.park(CoroutineScheduler.kt:847)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.tryPark(CoroutineScheduler.kt:792)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:740)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:693)
marcinmoskala
03/04/2024, 9:36 AMe5l
03/04/2024, 9:36 AMmarcinmoskala
03/04/2024, 9:37 AMmarcinmoskala
03/04/2024, 12:23 PM