#55, #644 Address comments

This commit is contained in:
Andras Slemmer 2017-05-09 10:38:50 +01:00
parent 5db4e4723d
commit f153e9a347
4 changed files with 40 additions and 46 deletions

View File

@ -42,7 +42,7 @@ class BootTests {
startNode(ALICE.name).getOrThrow()
}
// We count the number of nodes that wrote into the logfile by counting "Logs can be found in"
val numberOfNodesThatLogged = Files.lines(logFile.toPath()).filter { it.contains("Logs can be found in") }.count()
val numberOfNodesThatLogged = Files.lines(logFile.toPath()).filter { it.contains(LOGS_CAN_BE_FOUND_IN_STRING) }.count()
assertEquals(1, numberOfNodesThatLogged)
}
}

View File

@ -9,8 +9,8 @@ import net.corda.core.*
import net.corda.core.node.VersionInfo
import net.corda.core.utilities.Emoji
import net.corda.core.utilities.LogHelper.withLevel
import net.corda.node.internal.EnforceSingleNodeIsRunning
import net.corda.node.internal.Node
import net.corda.node.internal.enforceSingleNodeIsRunning
import net.corda.node.services.config.FullNodeConfiguration
import net.corda.node.shell.InteractiveShell
import net.corda.node.utilities.registration.HTTPNetworkRegistrationService
@ -36,6 +36,7 @@ fun printBasicNodeInfo(description: String, info: String? = null) {
}
val LOGS_DIRECTORY_NAME = "logs"
val LOGS_CAN_BE_FOUND_IN_STRING = "Logs can be found in"
private val log by lazy { LoggerFactory.getLogger("Main") }
private fun initLogging(cmdlineOptions: CmdLineOptions) {
@ -64,10 +65,9 @@ fun main(args: Array<String>) {
exitProcess(1)
}
val enforceSingleNodeIsRunning = EnforceSingleNodeIsRunning(cmdlineOptions.baseDirectory)
// We do the single node check before we initialise logging so that in case of a double-node start it doesn't mess
// with the running node's logs.
enforceSingleNodeIsRunning.start()
enforceSingleNodeIsRunning(cmdlineOptions.baseDirectory)
initLogging(cmdlineOptions)
disableJavaDeserialization() // Should be after initLogging to avoid TMI.
@ -97,7 +97,7 @@ fun main(args: Array<String>) {
drawBanner(versionInfo)
printBasicNodeInfo("Logs can be found in", System.getProperty("log-path"))
printBasicNodeInfo(LOGS_CAN_BE_FOUND_IN_STRING, System.getProperty("log-path"))
val conf = try {
cmdlineOptions.loadConfig()

View File

@ -340,15 +340,18 @@ class ShutdownManager(private val executorService: ExecutorService) {
}
val shutdowns = shutdownFutures.map { ErrorOr.catch { it.get(1, SECONDS) } }
shutdowns.reversed().forEach { errorOrShutdown ->
try {
if (errorOrShutdown.error == null) {
errorOrShutdown.value?.invoke()
} else {
log.error("Exception while getting shutdown method, disregarding", errorOrShutdown.error)
}
} catch (throwable: Throwable) {
log.error("Exception while shutting down", throwable)
}
errorOrShutdown.match(
onValue = { shutdown ->
try {
shutdown()
} catch (throwable: Throwable) {
log.error("Exception while shutting down", throwable)
}
},
onError = { error ->
log.error("Exception while getting shutdown method, disregarding", error)
}
)
}
}

View File

@ -7,38 +7,29 @@ import java.lang.management.ManagementFactory
import java.nio.file.Path
/**
* This class enforces that only a single node is running using the given [baseDirectory] by using a file lock.
* This function enforces that only a single node is running using the given [baseDirectory] by using a file lock.
*/
class EnforceSingleNodeIsRunning(val baseDirectory: Path) {
private companion object {
val log = loggerFor<EnforceSingleNodeIsRunning>()
}
fun start() {
// Write out our process ID (which may or may not resemble a UNIX process id - to us it's just a string) to a
// file that we'll do our best to delete on exit. But if we don't, it'll be overwritten next time. If it already
// exists, we try to take the file lock first before replacing it and if that fails it means we're being started
// twice with the same directory: that's a user error and we should bail out.
val pidPath = baseDirectory / "process-id"
val pidFile = pidPath.toFile()
if (!pidFile.exists()) {
pidFile.createNewFile()
}
pidFile.deleteOnExit()
val pidFileRw = RandomAccessFile(pidFile, "rw")
val pidFileLock = pidFileRw.channel.tryLock()
if (pidFileLock == null) {
log.error("It appears there is already a node running with the specified data directory $baseDirectory")
log.error("Shut that other node down and try again. It may have process ID ${pidFile.readText()}")
System.exit(1)
}
// Avoid the lock being garbage collected. We don't really need to release it as the OS will do so for us
// when our process shuts down, but we try in stop() anyway just to be nice.
Runtime.getRuntime().addShutdownHook(Thread {
pidFileLock.release()
})
val ourProcessID: String = ManagementFactory.getRuntimeMXBean().name.split("@")[0]
pidFileRw.setLength(0)
pidFileRw.write(ourProcessID.toByteArray())
fun enforceSingleNodeIsRunning(baseDirectory: Path) {
// Write out our process ID (which may or may not resemble a UNIX process id - to us it's just a string) to a
// file that we'll do our best to delete on exit. But if we don't, it'll be overwritten next time. If it already
// exists, we try to take the file lock first before replacing it and if that fails it means we're being started
// twice with the same directory: that's a user error and we should bail out.
val pidFile = (baseDirectory / "process-id").toFile()
pidFile.createNewFile()
pidFile.deleteOnExit()
val pidFileRw = RandomAccessFile(pidFile, "rw")
val pidFileLock = pidFileRw.channel.tryLock()
if (pidFileLock == null) {
println("It appears there is already a node running with the specified data directory $baseDirectory")
println("Shut that other node down and try again. It may have process ID ${pidFile.readText()}")
System.exit(1)
}
// Avoid the lock being garbage collected. We don't really need to release it as the OS will do so for us
// when our process shuts down, but we try in stop() anyway just to be nice.
Runtime.getRuntime().addShutdownHook(Thread {
pidFileLock.release()
})
val ourProcessID: String = ManagementFactory.getRuntimeMXBean().name.split("@")[0]
pidFileRw.setLength(0)
pidFileRw.write(ourProcessID.toByteArray())
}