mirror of
https://github.com/corda/corda.git
synced 2025-04-07 19:34:41 +00:00
parent
5db4e4723d
commit
f153e9a347
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user