asavio
01/08/2023, 7:35 AMIs Virtual Thread: false | Thread[#38,http-nio-8080-exec-3,5,main]
Is Virtual Thread: false | Thread[#37,http-nio-8080-exec-2,5,main]
Is Virtual Thread: false | Thread[#41,http-nio-8080-exec-6,5,main]
Is Virtual Thread: false | Thread[#36,http-nio-8080-exec-1,5,main]
Is Virtual Thread: false | Thread[#39,http-nio-8080-exec-4,5,main]
The full code is here: https://github.com/aseemsavio/loomgraphql
Here’s the code:
package com.asavio.loomgraphql
import org.apache.coyote.ProtocolHandler
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
import org.springframework.boot.runApplication
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer
import org.springframework.context.annotation.Bean
import org.springframework.core.task.AsyncTaskExecutor
import org.springframework.core.task.support.TaskExecutorAdapter
import org.springframework.graphql.data.method.annotation.QueryMapping
import org.springframework.stereotype.Controller
import java.util.concurrent.Executors
@SpringBootApplication
class LoomgraphqlApplication
fun main(args: Array<String>) {
runApplication<LoomgraphqlApplication>(*args)
}
@Bean(TaskExecutionAutoConfiguration.APPLICATION_TASK_EXECUTOR_BEAN_NAME)
fun asyncTaskExecutor(): AsyncTaskExecutor? {
return TaskExecutorAdapter(Executors.newVirtualThreadPerTaskExecutor())
}
@Bean
fun protocolHandlerVirtualThreadExecutorCustomizer(): TomcatProtocolHandlerCustomizer<*>? {
return TomcatProtocolHandlerCustomizer { protocolHandler: ProtocolHandler ->
protocolHandler.executor = Executors.newVirtualThreadPerTaskExecutor()
}
}
@Controller
class PeopleController {
@QueryMapping
fun people(): List<Person> {
println("Is Virtual Thread: ${Thread.currentThread().isVirtual} | ${Thread.currentThread()}")
return listOf(
Person("jdgahjdagdahjdg", "Jon", 25),
Person("ddgahjdagdahjdg", "Snow", 26),
Person("gdgahjdagdahjdg", "Arya", 23),
Person("qdgahjdagdahjdg", "Stark", 21),
)
}
}
data class Person(val id: String, val name: String, val age: Int)
This is my build.gradle.kts file.
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "3.0.1"
id("io.spring.dependency-management") version "1.1.0"
id("org.graalvm.buildtools.native") version "0.9.18"
kotlin("jvm") version "1.8.0"
kotlin("plugin.spring") version "1.8.0"
}
group = "com.asavio"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_19
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-graphql")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework:spring-webflux")
testImplementation("org.springframework.graphql:spring-graphql-test")
}
val preview = "--enable-preview"
tasks.withType<org.springframework.boot.gradle.tasks.run.BootRun> {
jvmArgs = mutableListOf(preview)
}
tasks.withType<JavaExec> {
jvmArgs = mutableListOf(preview)
}
tasks.withType<JavaCompile> {
options.encoding = "UTF-8"
options.compilerArgs.add(preview)
options.compilerArgs.add("-Xlint:preview")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "19"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Riccardo Lippolis
01/08/2023, 5:01 PM@Bean
(so asyncTaskExecutor()
and protocolHandlerVirtualThreadExecutorCustomizer()
in a class annotated with @Configuration
, probably these beans are not being created nowArtyom Gornostayev
01/08/2023, 11:15 PMasavio
01/09/2023, 2:42 AMIs Virtual Thread: true | VirtualThread[#40]/runnable@ForkJoinPool-1-worker-1
Is Virtual Thread: true | VirtualThread[#50]/runnable@ForkJoinPool-1-worker-1
Is Virtual Thread: true | VirtualThread[#52]/runnable@ForkJoinPool-1-worker-1
Is Virtual Thread: true | VirtualThread[#54]/runnable@ForkJoinPool-1-worker-1
In case you’re wondering, why virtual threads instead of Kotlin, I thought virtual threads are better for support with legacy Java libraries (provided they don’t pin the VTs too much) 🙂