Skip to content

Commit 4961890

Browse files
ALikhachevSpace Team
authored andcommitted
[BTA] Run in-process build operations in a thread pool
This way, ThreadLocal values would not be attached to the build system threads allowing the classloader used for BTA to be collected by GC earlier. ^KT-81414 Verification Pending
1 parent bf30cb1 commit 4961890

File tree

2 files changed

+32
-3
lines changed
  • compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal
  • libraries/tools/kotlin-maven-plugin-test/src/it/test-multimodule-in-process

2 files changed

+32
-3
lines changed

compiler/build-tools/kotlin-build-tools-impl/src/main/kotlin/org/jetbrains/kotlin/buildtools/internal/KotlinToolchainsImpl.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
1616
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
1717
import org.jetbrains.kotlin.config.KotlinCompilerVersion
1818
import java.io.File
19+
import java.util.concurrent.Callable
1920
import java.util.concurrent.ConcurrentHashMap
21+
import java.util.concurrent.ExecutionException
22+
import java.util.concurrent.Executors
23+
import java.util.concurrent.Future
24+
import kotlin.lazy
2025

2126
internal class KotlinToolchainsImpl() : KotlinToolchains {
2227
private val buildIdToSessionFlagFile: MutableMap<ProjectId, File> = ConcurrentHashMap()
@@ -47,6 +52,11 @@ internal class KotlinToolchainsImpl() : KotlinToolchains {
4752
override val projectId: ProjectId,
4853
private val buildIdToSessionFlagFile: MutableMap<ProjectId, File>,
4954
) : KotlinToolchains.BuildSession {
55+
private val executorDelegate = lazy {
56+
Executors.newCachedThreadPool()
57+
}
58+
private val executor by executorDelegate
59+
5060
override fun <R> executeOperation(operation: BuildOperation<R>): R {
5161
return executeOperation(operation, logger = null)
5262
}
@@ -57,11 +67,31 @@ internal class KotlinToolchainsImpl() : KotlinToolchains {
5767
logger: KotlinLogger?,
5868
): R {
5969
check(operation is BuildOperationImpl<R>) { "Unknown operation type: ${operation::class.qualifiedName}" }
60-
return operation.execute(projectId, executionPolicy, logger)
70+
val operationBody: Callable<R> = { operation.execute(projectId, executionPolicy, logger) }
71+
return if (executionPolicy is ExecutionPolicy.InProcess) {
72+
unwrapExecutionException(executor.submit(operationBody))
73+
} else {
74+
operationBody.call()
75+
}
76+
}
77+
78+
/**
79+
* Attempts to retrieve the result of the computation from the given `Future` instance.
80+
* If the computation threw an exception, unwraps and rethrows the underlying cause of the exception.
81+
*/
82+
private fun <R> unwrapExecutionException(result: Future<R>): R {
83+
return try {
84+
result.get()
85+
} catch (e: ExecutionException) {
86+
throw e.cause ?: e
87+
}
6188
}
6289

6390
override fun close() {
6491
clearJarCaches()
92+
if (executorDelegate.isInitialized()) {
93+
executor.shutdown()
94+
}
6595
val file = buildIdToSessionFlagFile.remove(projectId) ?: return
6696
file.delete()
6797
}
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
invoker.environmentVariables.MAVEN_OPTS = -XX:MaxMetaspaceSize=150M
2-
invoker.buildResult = failure
1+
invoker.environmentVariables.MAVEN_OPTS = -XX:MaxMetaspaceSize=150M

0 commit comments

Comments
 (0)