Add an option to turn off daemon connection caching
diff --git a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt index 20cf078..bd3fe0d 100644 --- a/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt +++ b/libraries/tools/kotlin-gradle-plugin-integration-tests/src/test/kotlin/org/jetbrains/kotlin/gradle/ExecutionStrategyIT.kt
@@ -76,6 +76,17 @@ ) } + @DisplayName("Compilation via Kotlin daemon without caching connection") + @GradleTest + fun testDaemonWithoutCachingConnection(gradleVersion: GradleVersion) { + doTestExecutionStrategy( + gradleVersion, + KotlinCompilerExecutionStrategy.DAEMON, + addHeapDumpOptions = false, + cacheDaemonConnection = false + ) + } + @DisplayName("Compilation via Kotlin daemon with fallback strategy") @GradleTest fun testDaemonFallbackStrategy(gradleVersion: GradleVersion) { @@ -188,6 +199,7 @@ addHeapDumpOptions: Boolean = true, testFallbackStrategy: Boolean = false, shouldConfigureStrategyViaGradleProperty: Boolean = true, + cacheDaemonConnection: Boolean? = null, additionalProjectConfiguration: TestProject.() -> Unit = {}, ) { project( @@ -207,6 +219,9 @@ // add jvm option that JVM fails to parse add("-Pkotlin.daemon.jvmargs=-Xmxqwerty") } + if (cacheDaemonConnection != null) { + add("-Pkotlin.daemon.cacheConnection=$cacheDaemonConnection") + } }.toTypedArray() val expectedFinishStrategy = if (testFallbackStrategy) KotlinCompilerExecutionStrategy.OUT_OF_PROCESS else executionStrategy val finishMessage = "Finished executing kotlin compiler using $expectedFinishStrategy strategy" @@ -217,7 +232,8 @@ assertNoBuildWarnings() if (expectedFinishStrategy == KotlinCompilerExecutionStrategy.DAEMON) { - assertOutputContainsExactTimes("Creating a new connection to Kotlin Daemon", 1) + val connectionsCount = if (cacheDaemonConnection == false) 2 else 1 + assertOutputContainsExactTimes("Creating a new connection to Kotlin Daemon", connectionsCount) } else if (expectedFinishStrategy == KotlinCompilerExecutionStrategy.IN_PROCESS) { assertOutputContainsExactTimes("Creating a new classloader for Kotlin Compiler", 1) }
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerCacheService.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerCacheService.kt index f0f79fe..1fdc3a7 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerCacheService.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/compilerRunner/KotlinCompilerCacheService.kt
@@ -6,6 +6,7 @@ package org.jetbrains.kotlin.compilerRunner import org.gradle.api.Project +import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.services.BuildService import org.gradle.api.services.BuildServiceParameters @@ -13,11 +14,16 @@ import org.jetbrains.kotlin.daemon.client.CompileServiceSession import org.jetbrains.kotlin.daemon.common.* import org.jetbrains.kotlin.gradle.logging.kotlinDebug +import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider import org.jetbrains.kotlin.gradle.utils.registerSharedService import java.io.File import java.net.URLClassLoader -internal abstract class KotlinCompilerCacheService : BuildService<BuildServiceParameters.None>, AutoCloseable { +internal abstract class KotlinCompilerCacheService : BuildService<KotlinCompilerCacheService.Parameters>, AutoCloseable { + interface Parameters : BuildServiceParameters { + val cacheDaemonConnection: Property<Boolean> + } + private data class DaemonConnectionKey( val compilerId: CompilerId, val clientAliveFlagFile: File, @@ -29,6 +35,7 @@ private val daemonConnections = HashMap<DaemonConnectionKey, CompileServiceSession?>() private val classloaders = HashMap<CompilerId, URLClassLoader>() + private val cacheDaemonConnection = parameters.cacheDaemonConnection.get() @Synchronized override fun close() { @@ -86,39 +93,42 @@ ) } } - val key = DaemonConnectionKey( - compilerId = compilerId, - clientAliveFlagFile = clientAliveFlagFile, - sessionAliveFlagFile = sessionAliveFlagFile, - isDebugEnabled = isDebugEnabled, - daemonOptions = daemonOptions, - daemonJVMOptions = daemonJvmOptions - ) - val existingConnection = daemonConnections[key] - if (existingConnection != null) { - if (existingConnection.compileService.isAlive().isGood) { - return existingConnection - } else { - daemonConnections.remove(existingConnection) - } + + fun newDaemonConnection(): CompileServiceSession? { + log.kotlinDebug { "Creating a new connection to Kotlin Daemon" } + return KotlinCompilerRunnerUtils.newDaemonConnection( + compilerId = compilerId, + clientAliveFlagFile = clientAliveFlagFile, + sessionAliveFlagFile = sessionAliveFlagFile, + isDebugEnabled = isDebugEnabled, + daemonOptions = daemonOptions, + daemonJVMOptions = daemonJvmOptions, + messageCollector = if (isDebugEnabled) messageCollector else MessageCollector.NONE + ) } - log.kotlinDebug { "Creating a new connection to Kotlin Daemon" } - val newConnection = KotlinCompilerRunnerUtils.newDaemonConnection( - compilerId = compilerId, - clientAliveFlagFile = clientAliveFlagFile, - sessionAliveFlagFile = sessionAliveFlagFile, - isDebugEnabled = isDebugEnabled, - daemonOptions = daemonOptions, - daemonJVMOptions = daemonJvmOptions, - messageCollector = if (isDebugEnabled) messageCollector else MessageCollector.NONE - ) - daemonConnections[key] = newConnection - return newConnection + return if (cacheDaemonConnection) { + val key = DaemonConnectionKey( + compilerId = compilerId, + clientAliveFlagFile = clientAliveFlagFile, + sessionAliveFlagFile = sessionAliveFlagFile, + isDebugEnabled = isDebugEnabled, + daemonOptions = daemonOptions, + daemonJVMOptions = daemonJvmOptions + ) + val cachedConnection = daemonConnections[key] + if (cachedConnection != null && cachedConnection.compileService.isAlive().isGood) { + cachedConnection + } else { + newDaemonConnection().also { daemonConnections[key] = it } + } + } else newDaemonConnection() } companion object { - fun registerIfAbsent(project: Project): Provider<KotlinCompilerCacheService> = - project.gradle.registerSharedService() + fun registerIfAbsent(project: Project, properties: PropertiesProvider): Provider<KotlinCompilerCacheService> = + project.gradle.registerSharedService { + parameters.cacheDaemonConnection.set(properties.cacheDaemonConnection) + } } } \ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt index a6de58f..ec4487c 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/plugin/PropertiesProvider.kt
@@ -458,6 +458,9 @@ val kotlinDaemonJvmArgs: String? get() = this.property("kotlin.daemon.jvmargs") + val cacheDaemonConnection: Boolean + get() = booleanProperty("kotlin.daemon.cacheConnection") ?: true + val kotlinCompilerExecutionStrategy: KotlinCompilerExecutionStrategy get() = KotlinCompilerExecutionStrategy.fromProperty( this.property("kotlin.compiler.execution.strategy")?.toLowerCaseAsciiOnly()
diff --git a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt index c324bb5..2e8820d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/common/kotlin/org/jetbrains/kotlin/gradle/tasks/configuration/AbstractKotlinCompileConfig.kt
@@ -66,7 +66,7 @@ task.buildReportsService.value(it) } } - KotlinCompilerCacheService.registerIfAbsent(project).also { + KotlinCompilerCacheService.registerIfAbsent(project, propertiesProvider).also { task.usesService(it) task.compilerCache.value(it) }