Antonio Acuña Prieto
06/01/2024, 9:03 AMget {
Thread.currentThread().name // eventLoopGroupProxy-4-1
coroutineContext[ContinuationInterceptor] // NettyDispatcher@444e12d2
launch(Dispatchers.Default) {
Thread.currentThread().name // DefaultDispatcher-worker-1
coroutineContext[ContinuationInterceptor] // Dispatchers.Default
withContext(Dispatchers.IO) {
Thread.currentThread().name // DefaultDispatcher-worker-1
coroutineContext[ContinuationInterceptor] // Dispatchers.IO
}
}
}
• I am assuming well if I say that Default dispatcher and IO dispatcher works both on the same type of thread?
• The Default dispatcher is either a dispatcher as such or it is one of the other dispatchers configured to be the default dispatcher?Sam
06/01/2024, 11:17 AMAntonio Acuña Prieto
06/01/2024, 11:30 AMStylianos Gakis
06/01/2024, 3:20 PMAntonio Acuña Prieto
06/01/2024, 3:40 PMAntonio Acuña Prieto
06/01/2024, 3:45 PMget {
Thread.currentThread().name // eventLoopGroupProxy-4-1
coroutineContext[ContinuationInterceptor] // NettyDispatcher@444e12d2
launch(Dispatchers.Default) {
Thread.currentThread().name // DefaultDispatcher-worker-1
coroutineContext[ContinuationInterceptor] // Dispatchers.Default
withContext(Dispatchers.IO) {
Thread.currentThread().name // DefaultDispatcher-worker-1
coroutineContext[ContinuationInterceptor] // Dispatchers.IO
}
}
}
NettyDispatcher
• Usage: Specific to Ktor when using Netty as the server.
• Purpose: Handles non-blocking I/O operations for network connections.
• Characteristics:
◦ Optimized for network and asynchronous I/O operations.
◦ Utilizes Netty's EventLoopGroup threads, which are lightweight and manage multiple connections efficiently.
• Example Use: Processing incoming HTTP requests without blocking.
Dispatchers.Default
• Usage: General purpose in Kotlin coroutines for CPU-intensive operations.
• Purpose: Execute tasks that require heavy CPU usage, such as complex computations or data processing.
• Characteristics:
◦ Uses a thread pool that adjusts according to the system's load and available CPUs.
◦ Suitable for non-blocking CPU-consuming tasks.
• Example Use: Data processing algorithms, mathematical computations.
Dispatchers.IO
• Usage: General purpose in Kotlin coroutines for blocking I/O operations.
• Purpose: Handle I/O tasks that may block, such as database accesses, file reading/writing, synchronous network calls.
• Characteristics:
◦ Optimized for blocking I/O operations.
◦ Uses a larger thread pool than Dispatchers.Default
to handle the blocking nature of I/O tasks.
• Example Use: Database queries, file system access, synchronous network calls.
Is this correct for you?Antonio Acuña Prieto
06/01/2024, 3:50 PMAntonio Acuña Prieto
06/01/2024, 5:03 PMrouting {
get("/default") {
queryDatabase()
call.respond(HttpStatusCode.OK)
}
get("/io") {
withContext(Dispatchers.IO) {
queryDatabase()
call.respond(HttpStatusCode.OK)
}
}
}
fun queryDatabase(): String {
// Simulate a blocking I/O operation
Thread.sleep(2000) // This blocks the current thread
return "Database query result"
}
I run this against K6 to test performance and then I ask GPT to summarize the results, so interesting:
Execution 1 to /default using event loop thread and netty dispatcher:
Metrics:
Status: 100% (240 requests, all successful)
Data Received: 9.1 kB (185 B/s)
Data Sent: 22 kB (453 B/s)
HTTP Requests Blocked: Avg 1.72ms
HTTP Requests Duration: Avg 15.76s
HTTP Requests Waiting: Avg 15.76s
HTTP Requests Receiving: Avg 35.14µs
HTTP Requests Sending: Avg 12.14µs
Iterations: 240 (4.87/s)
Virtual Users (VUs): 10 initially, max 100
Observations:
Request Duration: Very high average duration of 15.76 seconds.
Iterations: Completed 240 iterations.
VUs: Peaked at 100 VUs.
Overall Performance: Poor, indicating significant blocking or high latency.
Execution 2 to /io using worker thread and IO dispatcher:
Metrics:
Status: 100% (968 requests, all successful)
Data Received: 37 kB (1.1 kB/s)
Data Sent: 85 kB (2.6 kB/s)
HTTP Requests Blocked: Avg 392.96µs
HTTP Requests Duration: Avg 2.22s
HTTP Requests Waiting: Avg 2.22s
HTTP Requests Receiving: Avg 23.83µs
HTTP Requests Sending: Avg 24.94µs
Iterations: 968 (29.29/s)
Virtual Users (VUs): 8 initially, max 100
Observations:
Request Duration: Significantly lower average duration of 2.22 seconds.
Iterations: Completed 968 iterations.
VUs: Peaked at 100 VUs.
Overall Performance: Much better, indicating lower blocking and improved handling of requests.