Use connect-and-lease when using daemon in JPS & Gradle
Relates to KT-15562 "Service is dying". This commit includes multiple changes: 1. JPS & Gradle daemon clients are refactored to use `connectAndLease` from `KotlinCompilerClient`. `connectAndLease` was introduced in previous commits 2. `withKotlin` was removed because `connectAndLease` already covers retrying on connection error 3. Gradle flag files creation is changed: * client-alive flag file lives as long as Gradle instance lives, * session-alive flag file lives until the end of a build.
This commit is contained in:
+18
-38
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil
|
||||
import org.jetbrains.kotlin.daemon.client.CompileServiceSession
|
||||
import org.jetbrains.kotlin.daemon.client.CompilationServices
|
||||
import org.jetbrains.kotlin.daemon.client.DaemonReportMessage
|
||||
import org.jetbrains.kotlin.daemon.client.DaemonReportingTargets
|
||||
@@ -54,12 +55,16 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
|
||||
|
||||
protected abstract val log: KotlinLogger
|
||||
|
||||
class DaemonConnection(val daemon: CompileService?, val sessionId: Int = CompileService.NO_SESSION)
|
||||
|
||||
protected abstract fun getDaemonConnection(environment: Env): DaemonConnection
|
||||
protected abstract fun getDaemonConnection(environment: Env): CompileServiceSession?
|
||||
|
||||
@Synchronized
|
||||
protected fun newDaemonConnection(compilerId: CompilerId, flagFile: File, environment: Env, daemonOptions: DaemonOptions = configureDaemonOptions()): DaemonConnection {
|
||||
protected fun newDaemonConnection(
|
||||
compilerId: CompilerId,
|
||||
clientAliveFlagFile: File,
|
||||
sessionAliveFlagFile: File,
|
||||
environment: Env,
|
||||
daemonOptions: DaemonOptions = configureDaemonOptions()
|
||||
): CompileServiceSession? {
|
||||
val daemonJVMOptions = configureDaemonJVMOptions(inheritMemoryLimits = true, inheritAdditionalProperties = true)
|
||||
|
||||
val daemonReportMessages = ArrayList<DaemonReportMessage>()
|
||||
@@ -71,13 +76,19 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
|
||||
val profiler = if (daemonOptions.reportPerf) WallAndThreadAndMemoryTotalProfiler(withGC = false) else DummyProfiler()
|
||||
|
||||
val connection = profiler.withMeasure(null) {
|
||||
val daemon = KotlinCompilerClient.connectToCompileService(compilerId, daemonJVMOptions, daemonOptions, daemonReportingTargets, true, true)
|
||||
DaemonConnection(daemon, daemon?.leaseCompileSession(flagFile.absolutePath)?.get() ?: CompileService.NO_SESSION)
|
||||
KotlinCompilerClient.connectAndLease(compilerId,
|
||||
clientAliveFlagFile,
|
||||
daemonJVMOptions,
|
||||
daemonOptions,
|
||||
daemonReportingTargets,
|
||||
autostart = true,
|
||||
leaseSession = true,
|
||||
sessionAliveFlagFile = sessionAliveFlagFile)
|
||||
}
|
||||
|
||||
for (msg in daemonReportMessages) {
|
||||
environment.messageCollector.report(CompilerMessageSeverity.INFO,
|
||||
(if (msg.category == DaemonReportCategory.EXCEPTION && connection.daemon == null) "Falling back to compilation without daemon due to error: " else "") + msg.message,
|
||||
(if (msg.category == DaemonReportCategory.EXCEPTION && connection == null) "Falling back to compilation without daemon due to error: " else "") + msg.message,
|
||||
CompilerMessageLocation.NO_LOCATION)
|
||||
}
|
||||
|
||||
@@ -141,37 +152,6 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
|
||||
environment: Env
|
||||
): ExitCode?
|
||||
|
||||
protected fun <T> withDaemon(environment: Env, retryOnConnectionError: Boolean, fn: (CompileService, sessionId: Int)->T): T? {
|
||||
fun retryOrFalse(e: Exception): T? {
|
||||
if (retryOnConnectionError) {
|
||||
log.debug("retrying once on daemon connection error: ${e.message}")
|
||||
return withDaemon(environment, retryOnConnectionError = false, fn = fn)
|
||||
}
|
||||
log.info("daemon connection error: ${e.message}")
|
||||
return null
|
||||
}
|
||||
|
||||
log.debug("Try to connect to daemon")
|
||||
val connection = getDaemonConnection(environment)
|
||||
|
||||
if (connection.daemon != null) {
|
||||
log.info("Connected to daemon")
|
||||
|
||||
try {
|
||||
return fn(connection.daemon, connection.sessionId)
|
||||
}
|
||||
catch (e: java.rmi.ConnectException) {
|
||||
return retryOrFalse(e)
|
||||
}
|
||||
catch (e: java.rmi.UnmarshalException) {
|
||||
return retryOrFalse(e)
|
||||
}
|
||||
}
|
||||
|
||||
log.info("Daemon not found")
|
||||
return null
|
||||
}
|
||||
|
||||
protected fun exitCodeFromProcessExitCode(code: Int): ExitCode {
|
||||
val exitCode = ExitCode.values().find { it.code == code }
|
||||
if (exitCode != null) return exitCode
|
||||
|
||||
Reference in New Issue
Block a user