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)
             }