diff --git a/build.gradle.kts b/build.gradle.kts index 6845fb5..33d7ed5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -24,6 +24,26 @@ dependencyManagement { group = "io.github.reactivecircus.kstreamlined.backend" version = "0.0.1-SNAPSHOT" +graalvmNative { + metadataRepository { + enabled.set(true) + } + binaries.configureEach { + resources.autodetect() + } + binaries.named("main") { + buildArgs( + "--strict-image-heap", + "-march=native", + "-R:MaxHeapSize=10m", + ) + javaLauncher = javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(21)) + vendor.set(JvmVendorSpec.GRAAL_VM) + } + } +} + tasks.withType().configureEach { packageName = "io.github.reactivecircus.kstreamlined.backend.schema.generated" } diff --git a/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/KSConfiguration.kt b/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/KSConfiguration.kt index 2bf4bae..e13a92e 100644 --- a/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/KSConfiguration.kt +++ b/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/KSConfiguration.kt @@ -1,14 +1,24 @@ package io.github.reactivecircus.kstreamlined.backend +import com.netflix.graphql.dgs.webflux.autoconfiguration.DgsWebfluxConfigurationProperties import io.github.reactivecircus.kstreamlined.backend.client.ClientConfigs import io.github.reactivecircus.kstreamlined.backend.client.FeedClient import io.github.reactivecircus.kstreamlined.backend.client.RealFeedClient -import io.ktor.client.engine.cio.CIO +import io.ktor.client.engine.cio.* +import org.springframework.aot.hint.annotation.RegisterReflectionForBinding import org.springframework.beans.factory.annotation.Value import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.ImportRuntimeHints @Configuration +@ImportRuntimeHints(KStreamlinedRuntimeHints::class) +@RegisterReflectionForBinding( + DgsWebfluxConfigurationProperties::class, + DgsWebfluxConfigurationProperties.DgsWebsocketConfigurationProperties::class, + DgsWebfluxConfigurationProperties.DgsGraphiQLConfigurationProperties::class, + DgsWebfluxConfigurationProperties.DgsSchemaJsonConfigurationProperties::class, +) class KSConfiguration { @Bean diff --git a/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/KStreamlinedRuntimeHints.kt b/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/KStreamlinedRuntimeHints.kt new file mode 100644 index 0000000..a9d13fe --- /dev/null +++ b/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/KStreamlinedRuntimeHints.kt @@ -0,0 +1,24 @@ +package io.github.reactivecircus.kstreamlined.backend + +import org.springframework.aot.hint.ExecutableMode +import org.springframework.aot.hint.RuntimeHints +import org.springframework.aot.hint.RuntimeHintsRegistrar +import org.springframework.aot.hint.TypeReference + +object KStreamlinedRuntimeHints : RuntimeHintsRegistrar { + override fun registerHints(hints: RuntimeHints, classLoader: ClassLoader?) { + hints.reflection() + .registerType( + TypeReference.of("com.github.benmanes.caffeine.cache.SSA") + ) { builder -> + builder.withConstructor( + listOf( + TypeReference.of("com.github.benmanes.caffeine.cache.Caffeine"), + TypeReference.of("com.github.benmanes.caffeine.cache.AsyncCacheLoader"), + TypeReference.of("boolean"), + ), + ExecutableMode.INVOKE, + ) + } + } +} diff --git a/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/datafetcher/FeedEntryDataFetcher.kt b/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/datafetcher/FeedEntryDataFetcher.kt index d2954e3..01a4229 100644 --- a/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/datafetcher/FeedEntryDataFetcher.kt +++ b/src/main/kotlin/io/github/reactivecircus/kstreamlined/backend/datafetcher/FeedEntryDataFetcher.kt @@ -33,8 +33,9 @@ import java.time.Duration @DgsComponent class FeedEntryDataFetcher( private val feedClient: FeedClient, - private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO, ) { + private val coroutineDispatcher: CoroutineDispatcher = Dispatchers.IO + private val kotlinBlogCacheContext = object : CacheContext { override val cache: Cache> = Caffeine .newBuilder()