From 166cbbf2e528576bbc792be4d83ac2c55818e8bf Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Mon, 13 Feb 2017 10:37:05 +0000 Subject: [PATCH] Add utility function for creating SLF4J loggers, and close unused I/O streams from forked processes. --- .../kotlin/net/corda/demobench/DemoBench.kt | 6 ++++++ .../net/corda/demobench/model/DBViewer.kt | 4 ++-- .../net/corda/demobench/model/Explorer.kt | 17 +++++++++++++++-- .../net/corda/demobench/model/WebServer.kt | 19 ++++++++++++++++--- .../kotlin/net/corda/demobench/pty/R3Pty.kt | 4 ++-- .../kotlin/net/corda/demobench/rpc/NodeRPC.kt | 4 ++-- .../corda/demobench/views/NodeTerminalView.kt | 6 ++++++ 7 files changed, 49 insertions(+), 11 deletions(-) diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/DemoBench.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/DemoBench.kt index 475cd97d38..b9447be9da 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/DemoBench.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/DemoBench.kt @@ -2,6 +2,8 @@ package net.corda.demobench import javafx.scene.image.Image import net.corda.demobench.views.DemoBenchView +import org.slf4j.Logger +import org.slf4j.LoggerFactory import tornadofx.App import tornadofx.addStageIcon @@ -50,3 +52,7 @@ class DemoBench : App(DemoBenchView::class) { } } +/* + * Trivial utility function to create SLF4J Logger. + */ +inline fun loggerFor(): Logger = LoggerFactory.getLogger(T::class.java) diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/DBViewer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/DBViewer.kt index fd4dd377a3..b6ba3f81ae 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/DBViewer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/DBViewer.kt @@ -1,14 +1,14 @@ package net.corda.demobench.model +import net.corda.demobench.loggerFor import org.h2.server.web.LocalWebServer import org.h2.tools.Server import org.h2.util.JdbcUtils -import org.slf4j.LoggerFactory import java.util.concurrent.Executors import kotlin.reflect.jvm.jvmName class DBViewer : AutoCloseable { - private val log = LoggerFactory.getLogger(DBViewer::class.java) + private val log = loggerFor() private val webServer: Server private val pool = Executors.newCachedThreadPool() diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt index 4323e74d2c..289b71c222 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt @@ -1,10 +1,10 @@ package net.corda.demobench.model -import org.slf4j.LoggerFactory +import net.corda.demobench.loggerFor import java.util.concurrent.Executors class Explorer(val explorerController: ExplorerController) : AutoCloseable { - private val log = LoggerFactory.getLogger(Explorer::class.java) + private val log = loggerFor() private val executor = Executors.newSingleThreadExecutor() private var process: Process? = null @@ -32,6 +32,11 @@ class Explorer(val explorerController: ExplorerController) : AutoCloseable { log.info("Launched Node Explorer for '{}'", config.legalName) + // Close these streams because no-one is using them. + safeClose(p.outputStream) + safeClose(p.inputStream) + safeClose(p.errorStream) + executor.submit { val exitValue = p.waitFor() process = null @@ -46,4 +51,12 @@ class Explorer(val explorerController: ExplorerController) : AutoCloseable { process?.destroy() } + private fun safeClose(c: AutoCloseable?) { + try { + c?.close() + } catch (e: Exception) { + log.error("Failed to close stream: '{}'", e.message) + } + } + } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/WebServer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/WebServer.kt index 977ad666a9..e60c12eff6 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/WebServer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/WebServer.kt @@ -1,10 +1,10 @@ package net.corda.demobench.model -import org.slf4j.LoggerFactory +import net.corda.demobench.loggerFor import java.util.concurrent.Executors class WebServer(val webServerController: WebServerController) : AutoCloseable { - private val log = LoggerFactory.getLogger(WebServer::class.java) + private val log = loggerFor() private val executor = Executors.newSingleThreadExecutor() private var process: Process? = null @@ -23,6 +23,11 @@ class WebServer(val webServerController: WebServerController) : AutoCloseable { log.info("Launched Web Server for '{}'", config.legalName) + // Close these streams because no-one is using them. + safeClose(p.outputStream) + safeClose(p.inputStream) + safeClose(p.errorStream) + executor.submit { val exitValue = p.waitFor() process = null @@ -37,4 +42,12 @@ class WebServer(val webServerController: WebServerController) : AutoCloseable { process?.destroy() } -} + private fun safeClose(c: AutoCloseable?) { + try { + c?.close() + } catch (e: Exception) { + log.error("Failed to close stream: '{}'", e.message) + } + } + +} \ No newline at end of file diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt index a52ee275e9..ba33c6fb55 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/pty/R3Pty.kt @@ -4,7 +4,7 @@ import com.jediterm.terminal.TtyConnector import com.jediterm.terminal.ui.* import com.jediterm.terminal.ui.settings.SettingsProvider import com.pty4j.PtyProcess -import org.slf4j.LoggerFactory +import net.corda.demobench.loggerFor import java.awt.* import java.nio.charset.StandardCharsets.UTF_8 @@ -13,7 +13,7 @@ import java.util.concurrent.Executors import java.util.concurrent.TimeUnit class R3Pty(val name: String, settings: SettingsProvider, dimension: Dimension, val onExit: () -> Unit) : AutoCloseable { - private val log = LoggerFactory.getLogger(R3Pty::class.java) + private val log = loggerFor() private val executor = Executors.newSingleThreadExecutor() diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt index 68881b02fd..b6f4065560 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt @@ -4,12 +4,12 @@ import com.google.common.net.HostAndPort import java.util.* import java.util.concurrent.TimeUnit.SECONDS import net.corda.core.messaging.CordaRPCOps +import net.corda.demobench.loggerFor import net.corda.demobench.model.NodeConfig import net.corda.node.services.messaging.CordaRPCClient -import org.slf4j.LoggerFactory class NodeRPC(config: NodeConfig, start: () -> Unit, invoke: (CordaRPCOps) -> Unit): AutoCloseable { - private val log = LoggerFactory.getLogger(NodeRPC::class.java) + private val log = loggerFor() companion object Data { private val ONE_SECOND = SECONDS.toMillis(1) diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt index 531a5dbcd8..e83b2d0ed4 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt @@ -107,6 +107,12 @@ class NodeTerminalView : Fragment() { } } + /* + * We only want to run one web server for each node. + * So disable the "launch" button when we have + * launched the web server and only reenable it when + * the web server has exited. + */ fun configureWebButton(config: NodeConfig) { launchWebButton.setOnAction { launchWebButton.isDisable = true