Generalizing daemon process shutdown mechanism
This commit is contained in:
@@ -32,6 +32,7 @@ import java.util.jar.Manifest
|
|||||||
import java.util.logging.Level
|
import java.util.logging.Level
|
||||||
import java.util.logging.LogManager
|
import java.util.logging.LogManager
|
||||||
import java.util.logging.Logger
|
import java.util.logging.Logger
|
||||||
|
import kotlin.concurrent.schedule
|
||||||
import kotlin.concurrent.timer
|
import kotlin.concurrent.timer
|
||||||
|
|
||||||
val DAEMON_PERIODIC_CHECK_INTERVAL_MS = 1000L
|
val DAEMON_PERIODIC_CHECK_INTERVAL_MS = 1000L
|
||||||
@@ -140,7 +141,17 @@ public object CompileDaemon {
|
|||||||
CompileService.TargetPlatform.JS -> js
|
CompileService.TargetPlatform.JS -> js
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val compilerService = CompileServiceImpl(registry, compilerSelector, compilerId, daemonOptions, port)
|
val compilerService = CompileServiceImpl(registry, compilerSelector, compilerId, daemonOptions, port,
|
||||||
|
onShutdown = {
|
||||||
|
if (daemonOptions.forceShutdownTimeoutMilliseconds != COMPILE_DAEMON_FORCE_SHUTDOWN_TIMEOUT_INFINITE) {
|
||||||
|
// running a watcher thread that ensures that if the daemon is not exited normally (may be due to RMI leftovers), it's forced to exit
|
||||||
|
// the watcher is a daemon thread, meaning it should not prevent JVM to exit normally
|
||||||
|
Timer(true).schedule(daemonOptions.forceShutdownTimeoutMilliseconds) {
|
||||||
|
log.info("force JVM shutdown")
|
||||||
|
System.exit(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
if (daemonOptions.runFilesPath.isNotEmpty())
|
if (daemonOptions.runFilesPath.isNotEmpty())
|
||||||
println(daemonOptions.runFilesPath)
|
println(daemonOptions.runFilesPath)
|
||||||
@@ -169,7 +180,7 @@ public object CompileDaemon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// stopping daemon if any shutdown condition is met
|
// stopping daemon if any shutdown condition is met
|
||||||
timer(initialDelay = DAEMON_PERIODIC_CHECK_INTERVAL_MS, period = DAEMON_PERIODIC_CHECK_INTERVAL_MS) {
|
timer(initialDelay = DAEMON_PERIODIC_CHECK_INTERVAL_MS, period = DAEMON_PERIODIC_CHECK_INTERVAL_MS, daemon = true) {
|
||||||
try {
|
try {
|
||||||
val idleSeconds = nowSeconds() - compilerService.lastUsedSeconds
|
val idleSeconds = nowSeconds() - compilerService.lastUsedSeconds
|
||||||
if (shutdownCondition({ !runFile.exists() }, "Run file removed, shutting down") ||
|
if (shutdownCondition({ !runFile.exists() }, "Run file removed, shutting down") ||
|
||||||
|
|||||||
@@ -27,12 +27,10 @@ import java.io.PrintStream
|
|||||||
import java.rmi.NoSuchObjectException
|
import java.rmi.NoSuchObjectException
|
||||||
import java.rmi.registry.Registry
|
import java.rmi.registry.Registry
|
||||||
import java.rmi.server.UnicastRemoteObject
|
import java.rmi.server.UnicastRemoteObject
|
||||||
import java.util.*
|
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||||
import java.util.logging.Logger
|
import java.util.logging.Logger
|
||||||
import kotlin.concurrent.read
|
import kotlin.concurrent.read
|
||||||
import kotlin.concurrent.schedule
|
|
||||||
import kotlin.concurrent.write
|
import kotlin.concurrent.write
|
||||||
|
|
||||||
fun nowSeconds() = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime())
|
fun nowSeconds() = TimeUnit.NANOSECONDS.toSeconds(System.nanoTime())
|
||||||
@@ -46,7 +44,8 @@ class CompileServiceImpl(
|
|||||||
val compiler: CompilerSelector,
|
val compiler: CompilerSelector,
|
||||||
val selfCompilerId: CompilerId,
|
val selfCompilerId: CompilerId,
|
||||||
val daemonOptions: DaemonOptions,
|
val daemonOptions: DaemonOptions,
|
||||||
port: Int
|
port: Int,
|
||||||
|
val onShutdown: () -> Unit
|
||||||
) : CompileService {
|
) : CompileService {
|
||||||
|
|
||||||
private val classpathWatcher = LazyClasspathWatcher(selfCompilerId.compilerClasspath)
|
private val classpathWatcher = LazyClasspathWatcher(selfCompilerId.compilerClasspath)
|
||||||
@@ -68,14 +67,7 @@ class CompileServiceImpl(
|
|||||||
alive = false
|
alive = false
|
||||||
UnicastRemoteObject.unexportObject(this, true)
|
UnicastRemoteObject.unexportObject(this, true)
|
||||||
log.info("Shutdown complete")
|
log.info("Shutdown complete")
|
||||||
if (daemonOptions.forceShutdownTimeoutMilliseconds != COMPILE_DAEMON_FORCE_SHUTDOWN_TIMEOUT_INFINITE) {
|
onShutdown()
|
||||||
// running a watcher thread that ensures that if the daemon is not exited normally (may be due to RMI leftovers), it's forced to exit
|
|
||||||
// the watcher is a daemon thread, meaning it should not prevent JVM to exit normally
|
|
||||||
Timer(true).schedule(daemonOptions.forceShutdownTimeoutMilliseconds) {
|
|
||||||
log.info("force JVM shutdown")
|
|
||||||
System.exit(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user