From a61c11acfc8d78f8cddc230c6bf1269fac2b57c4 Mon Sep 17 00:00:00 2001 From: Chris Stewart Date: Mon, 7 Jun 2021 11:38:33 -0500 Subject: [PATCH] Implement sharing of actor systems across the GUI and backend app server (#3220) * Implement sharing of actor systems across the GUI and backend app server * Add timestamp to system names * Fix test case --- .../org/bitcoins/bundle/gui/LandingPane.scala | 3 +- .../bundle/gui/LandingPaneModel.scala | 7 +- .../oracle/server/OracleServerMain.scala | 12 ++-- .../org/bitcoins/scripts/ScanBitcoind.scala | 12 +++- .../org/bitcoins/scripts/ZipDatadir.scala | 13 ++-- .../server/routes/BitcoinSRunner.scala | 7 +- .../bitcoins/server/util/BitcoinSApp.scala | 9 +++ .../org/bitcoins/server/LogLocationTest.scala | 67 +++++++++++++++++++ .../org/bitcoins/server/ServerRunTest.scala | 54 --------------- .../bitcoins/server/BitcoinSServerMain.scala | 12 ++-- 10 files changed, 118 insertions(+), 78 deletions(-) create mode 100644 app/server-routes/src/main/scala/org/bitcoins/server/util/BitcoinSApp.scala create mode 100644 app/server-test/src/test/scala/org/bitcoins/server/LogLocationTest.scala diff --git a/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPane.scala b/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPane.scala index 38247a8db4..5f27ae9d8b 100644 --- a/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPane.scala +++ b/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPane.scala @@ -1,5 +1,6 @@ package org.bitcoins.bundle.gui +import akka.actor.ActorSystem import org.bitcoins.gui._ import org.bitcoins.node.NodeType import org.bitcoins.server.BitcoinSAppConfig @@ -12,7 +13,7 @@ import scalafx.scene.text._ import scala.concurrent.ExecutionContext.global import scala.util.Try -class LandingPane(glassPane: VBox) { +class LandingPane(glassPane: VBox)(implicit system: ActorSystem) { val appConfig: BitcoinSAppConfig = BitcoinSAppConfig.fromDefaultDatadir()(global) diff --git a/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPaneModel.scala b/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPaneModel.scala index bf669aca04..55e26e1074 100644 --- a/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPaneModel.scala +++ b/app/bundle/src/main/scala/org/bitcoins/bundle/gui/LandingPaneModel.scala @@ -1,5 +1,6 @@ package org.bitcoins.bundle.gui +import akka.actor.ActorSystem import com.typesafe.config._ import org.bitcoins.bundle.gui.BundleGUI._ import org.bitcoins.gui._ @@ -14,7 +15,7 @@ import scala.concurrent.duration.DurationInt import scala.concurrent.{Await, Promise} import scala.jdk.CollectionConverters._ -class LandingPaneModel() { +class LandingPaneModel()(implicit system: ActorSystem) { var taskRunner: TaskRunner = _ // Sadly, it is a Java "pattern" to pass null into @@ -48,7 +49,9 @@ class LandingPaneModel() { changeToWalletGUIScene() promise.success(()) }(global) - BitcoinSServerMain.main(args.toArray) + + //use class base constructor to share the actor system + new BitcoinSServerMain(args.toArray).run() Await.result(promise.future, 60.seconds) } diff --git a/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleServerMain.scala b/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleServerMain.scala index 7906ba3dbf..00076ff41f 100644 --- a/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleServerMain.scala +++ b/app/oracle-server/src/main/scala/org/bitcoins/oracle/server/OracleServerMain.scala @@ -1,15 +1,16 @@ package org.bitcoins.oracle.server +import akka.actor.ActorSystem import org.bitcoins.dlc.oracle.config.DLCOracleAppConfig import org.bitcoins.server.routes.{BitcoinSRunner, Server} +import org.bitcoins.server.util.BitcoinSApp import scala.concurrent.Future -class OracleServerMain(override val args: Array[String]) +class OracleServerMain(override val args: Array[String])(implicit + override val system: ActorSystem) extends BitcoinSRunner { - override val actorSystemName = "bitcoin-s-oracle" - implicit val conf: DLCOracleAppConfig = DLCOracleAppConfig(datadir, baseConfig) @@ -58,6 +59,9 @@ class OracleServerMain(override val args: Array[String]) } } -object OracleServerMain extends App { +object OracleServerMain extends BitcoinSApp { + + override val actorSystemName = + s"bitcoin-s-oracle-${System.currentTimeMillis()}" new OracleServerMain(args).run(Some("oracle")) } diff --git a/app/scripts/src/main/scala/org/bitcoins/scripts/ScanBitcoind.scala b/app/scripts/src/main/scala/org/bitcoins/scripts/ScanBitcoind.scala index 58b1f0749a..6d54e8c532 100644 --- a/app/scripts/src/main/scala/org/bitcoins/scripts/ScanBitcoind.scala +++ b/app/scripts/src/main/scala/org/bitcoins/scripts/ScanBitcoind.scala @@ -1,12 +1,14 @@ package org.bitcoins.scripts import akka.NotUsed +import akka.actor.ActorSystem import akka.stream.scaladsl.{Keep, Sink, Source} import org.bitcoins.core.protocol.blockchain.Block import org.bitcoins.core.protocol.transaction.WitnessTransaction import org.bitcoins.rpc.client.common.BitcoindRpcClient import org.bitcoins.server.BitcoindRpcAppConfig import org.bitcoins.server.routes.BitcoinSRunner +import org.bitcoins.server.util.BitcoinSApp import scala.concurrent.Future @@ -15,8 +17,9 @@ import scala.concurrent.Future * between bitcoin-s and bitcoind inside of bitcoin-s.conf * @see https://bitcoin-s.org/docs/config/configuration#example-configuration-file */ -class ScanBitcoind(override val args: Array[String]) extends BitcoinSRunner { - override val actorSystemName = "scan-bitcoind" +class ScanBitcoind(override val args: Array[String])(implicit + override val system: ActorSystem) + extends BitcoinSRunner { implicit val rpcAppConfig: BitcoindRpcAppConfig = BitcoindRpcAppConfig(datadir, baseConfig) @@ -93,6 +96,9 @@ class ScanBitcoind(override val args: Array[String]) extends BitcoinSRunner { } } -object ScanBitcoind extends App { +object ScanBitcoind extends BitcoinSApp { + + override val actorSystemName: String = + s"scan-bitcoind-${System.currentTimeMillis()}" new ScanBitcoind(args).run() } diff --git a/app/scripts/src/main/scala/org/bitcoins/scripts/ZipDatadir.scala b/app/scripts/src/main/scala/org/bitcoins/scripts/ZipDatadir.scala index bcda89b13b..5d30f5b5eb 100644 --- a/app/scripts/src/main/scala/org/bitcoins/scripts/ZipDatadir.scala +++ b/app/scripts/src/main/scala/org/bitcoins/scripts/ZipDatadir.scala @@ -1,15 +1,17 @@ package org.bitcoins.scripts +import akka.actor.ActorSystem import org.bitcoins.server.BitcoinSAppConfig import org.bitcoins.server.routes.BitcoinSRunner +import org.bitcoins.server.util.BitcoinSApp import java.nio.file.Paths import scala.concurrent.Future /** This script zips your $HOME/.bitcoin-s/ directory to a specified path, excluding chaindb.sqlite */ -class ZipDatadir(override val args: Array[String]) extends BitcoinSRunner { - - override def actorSystemName: String = "Zip-datadir" +class ZipDatadir(override val args: Array[String])(implicit + override val system: ActorSystem) + extends BitcoinSRunner { implicit lazy val conf: BitcoinSAppConfig = BitcoinSAppConfig(datadir, baseConfig) @@ -28,6 +30,9 @@ class ZipDatadir(override val args: Array[String]) extends BitcoinSRunner { override def stop(): Future[Unit] = Future.unit } -object Zip extends App { +object Zip extends BitcoinSApp { + + override val actorSystemName: String = + s"zip-datadir-${System.currentTimeMillis()}" new ZipDatadir(args).run() } diff --git a/app/server-routes/src/main/scala/org/bitcoins/server/routes/BitcoinSRunner.scala b/app/server-routes/src/main/scala/org/bitcoins/server/routes/BitcoinSRunner.scala index 91bea82498..c310234163 100644 --- a/app/server-routes/src/main/scala/org/bitcoins/server/routes/BitcoinSRunner.scala +++ b/app/server-routes/src/main/scala/org/bitcoins/server/routes/BitcoinSRunner.scala @@ -16,13 +16,8 @@ trait BitcoinSRunner extends StartStopAsync[Unit] with Logging { protected def args: Array[String] - def actorSystemName: String + implicit def system: ActorSystem - implicit lazy val system: ActorSystem = { - val system = ActorSystem(actorSystemName, baseConfig) - system.log.info("Akka started") - system - } implicit lazy val ec: ExecutionContext = system.dispatcher lazy val argsWithIndex: Vector[(String, Int)] = args.toVector.zipWithIndex diff --git a/app/server-routes/src/main/scala/org/bitcoins/server/util/BitcoinSApp.scala b/app/server-routes/src/main/scala/org/bitcoins/server/util/BitcoinSApp.scala new file mode 100644 index 0000000000..e1f08f11b5 --- /dev/null +++ b/app/server-routes/src/main/scala/org/bitcoins/server/util/BitcoinSApp.scala @@ -0,0 +1,9 @@ +package org.bitcoins.server.util + +import akka.actor.ActorSystem + +trait BitcoinSApp extends App { + def actorSystemName: String + + implicit lazy val system: ActorSystem = ActorSystem(actorSystemName) +} diff --git a/app/server-test/src/test/scala/org/bitcoins/server/LogLocationTest.scala b/app/server-test/src/test/scala/org/bitcoins/server/LogLocationTest.scala new file mode 100644 index 0000000000..ccc5982792 --- /dev/null +++ b/app/server-test/src/test/scala/org/bitcoins/server/LogLocationTest.scala @@ -0,0 +1,67 @@ +package org.bitcoins.server + +import org.bitcoins.rpc.client.common.BitcoindVersion +import org.bitcoins.rpc.util.RpcUtil +import org.bitcoins.testkit.BitcoinSTestAppConfig +import org.bitcoins.testkit.fixtures.BitcoinSFixture +import org.bitcoins.testkit.util.{AkkaUtil, BitcoinSAsyncTest} +import scala.concurrent.duration.DurationInt +import java.nio.file.Files +import scala.reflect.io.Directory + +class LogLocationTest extends BitcoinSAsyncTest { + + behavior of "LogLocationTest" + + it must "start up and log to the correct location" in { + val datadir = BitcoinSTestAppConfig.tmpDir() + val directory = new Directory(datadir.toFile) + val confFile = datadir.resolve("bitcoin-s.conf") + + for { + bitcoind <- + BitcoinSFixture.createBitcoindWithFunds(Some(BitcoindVersion.V21)) + + // Make it so we connect to the correct bitcoind + port = bitcoind.instance.uri.getPort + confStr = s"""bitcoin-s.node.peers = ["localhost:$port"]""" + _ = Files.write(confFile, confStr.getBytes) + + // Add config options + randPort = RpcUtil.randomPort + args = Array("--datadir", + datadir.toAbsolutePath.toString, + "--rpcport", + randPort.toString) + + main = new BitcoinSServerMain(args) + + // Start the server in a separate thread + runnable = new Runnable { + override def run(): Unit = { + main.run() + } + } + thread = new Thread(runnable) + _ = thread.start() + // Wait for the server to have successfully started up + _ <- AkkaUtil.nonBlockingSleep(1.second) + binding <- BitcoinSServer.startedF + + // Stop the server + _ <- bitcoind.stop() + _ <- binding.terminate(5.seconds) + _ = thread.interrupt() + _ <- main.stop() + } yield { + // Cleanup + directory.deleteRecursively() + + val expectedDir = datadir.resolve("regtest") + + // Check the log location was correctly set + assert( + System.getProperty("bitcoins.log.location") == expectedDir.toString) + } + } +} diff --git a/app/server-test/src/test/scala/org/bitcoins/server/ServerRunTest.scala b/app/server-test/src/test/scala/org/bitcoins/server/ServerRunTest.scala index bd30e80a12..36bd1485cb 100644 --- a/app/server-test/src/test/scala/org/bitcoins/server/ServerRunTest.scala +++ b/app/server-test/src/test/scala/org/bitcoins/server/ServerRunTest.scala @@ -1,13 +1,10 @@ package org.bitcoins.server -import org.bitcoins.rpc.client.common.BitcoindVersion import org.bitcoins.rpc.util.RpcUtil import org.bitcoins.testkit.BitcoinSTestAppConfig -import org.bitcoins.testkit.fixtures.BitcoinSFixture import org.bitcoins.testkit.util.{AkkaUtil, BitcoinSAsyncTest} import org.scalatest.Assertion -import java.nio.file._ import scala.concurrent.Future import scala.concurrent.duration.DurationInt import scala.reflect.io.Directory @@ -54,55 +51,4 @@ class ServerRunTest extends BitcoinSAsyncTest { } yield succeed } - it must "start up and log to the correct location" in { - val datadir = BitcoinSTestAppConfig.tmpDir() - val directory = new Directory(datadir.toFile) - val confFile = datadir.resolve("bitcoin-s.conf") - - for { - bitcoind <- - BitcoinSFixture.createBitcoindWithFunds(Some(BitcoindVersion.V21)) - - // Make it so we connect to the correct bitcoind - port = bitcoind.instance.uri.getPort - confStr = s"""bitcoin-s.node.peers = ["localhost:$port"]""" - _ = Files.write(confFile, confStr.getBytes) - - // Add config options - randPort = RpcUtil.randomPort - args = Array("--datadir", - datadir.toAbsolutePath.toString, - "--rpcport", - randPort.toString) - - main = new BitcoinSServerMain(args) - - // Start the server in a separate thread - runnable = new Runnable { - override def run(): Unit = { - main.run() - } - } - thread = new Thread(runnable) - _ = thread.start() - // Wait for the server to have successfully started up - _ <- AkkaUtil.nonBlockingSleep(1.second) - binding <- BitcoinSServer.startedF - - // Stop the server - _ <- bitcoind.stop() - _ <- binding.terminate(5.seconds) - _ = thread.interrupt() - _ <- main.stop() - } yield { - // Cleanup - directory.deleteRecursively() - - val expectedDir = datadir.resolve("regtest") - - // Check the log location was correctly set - assert( - System.getProperty("bitcoins.log.location") == expectedDir.toString) - } - } } diff --git a/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala b/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala index 669d85cd0c..041ec65dee 100644 --- a/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala +++ b/app/server/src/main/scala/org/bitcoins/server/BitcoinSServerMain.scala @@ -21,16 +21,16 @@ import org.bitcoins.node.config.NodeAppConfig import org.bitcoins.node.models.Peer import org.bitcoins.rpc.config.ZmqConfig import org.bitcoins.server.routes.{BitcoinSRunner, Server} +import org.bitcoins.server.util.BitcoinSApp import org.bitcoins.wallet.Wallet import org.bitcoins.wallet.config.WalletAppConfig import scala.concurrent.{ExecutionContext, Future, Promise} -class BitcoinSServerMain(override val args: Array[String]) +class BitcoinSServerMain(override val args: Array[String])(implicit + override val system: ActorSystem) extends BitcoinSRunner { - override val actorSystemName = "bitcoin-s-server" - implicit lazy val conf: BitcoinSAppConfig = BitcoinSAppConfig(datadir, baseConfig) @@ -374,7 +374,11 @@ class BitcoinSServerMain(override val args: Array[String]) } } -object BitcoinSServerMain extends App { +object BitcoinSServerMain extends BitcoinSApp { + + override val actorSystemName = + s"bitcoin-s-server-${System.currentTimeMillis()}" + new BitcoinSServerMain(args).run() }