From c8819afe53866cb38cbdf8c38f2eb10a275e6ddf Mon Sep 17 00:00:00 2001 From: Lukas Sembera Date: Sat, 31 Dec 2016 14:40:01 +0100 Subject: [PATCH] Use nanoTime() instead of now() for durations --- .../scala/eu/semberal/dbstress/Defaults.scala | 14 -------------- src/main/scala/eu/semberal/dbstress/Main.scala | 4 ++-- .../eu/semberal/dbstress/Orchestrator.scala | 2 +- src/main/scala/eu/semberal/dbstress/Utils.scala | 16 ++++++++++++++++ .../semberal/dbstress/actor/DatabaseActor.scala | 15 ++++++++------- .../eu/semberal/dbstress/model/Results.scala | 15 ++++----------- .../semberal/dbstress/util/ResultsExport.scala | 5 ++--- .../dbstress/model/UnitSummaryTest.scala | 16 +++++++--------- 8 files changed, 40 insertions(+), 47 deletions(-) delete mode 100644 src/main/scala/eu/semberal/dbstress/Defaults.scala create mode 100644 src/main/scala/eu/semberal/dbstress/Utils.scala diff --git a/src/main/scala/eu/semberal/dbstress/Defaults.scala b/src/main/scala/eu/semberal/dbstress/Defaults.scala deleted file mode 100644 index 6cd4490..0000000 --- a/src/main/scala/eu/semberal/dbstress/Defaults.scala +++ /dev/null @@ -1,14 +0,0 @@ -package eu.semberal.dbstress - -import java.time.format.DateTimeFormatter - -import scala.concurrent.duration.DurationInt - -object Defaults { - val filePathFriendlyDateTimeFormat = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss") - - val ScenarioTimeout = (24*60*60).seconds - - val ActorSystemShutdownTimeout = 20.seconds - -} diff --git a/src/main/scala/eu/semberal/dbstress/Main.scala b/src/main/scala/eu/semberal/dbstress/Main.scala index db0e8fb..6463f5d 100644 --- a/src/main/scala/eu/semberal/dbstress/Main.scala +++ b/src/main/scala/eu/semberal/dbstress/Main.scala @@ -74,7 +74,7 @@ object Main extends LazyLogging { val future: Future[Unit] = new Orchestrator(system).run(sc, exports) val bugMsg = "This is most likely an application bug. Please, file an issue in the dbstress bug tracker" val exitStatus: Int = try { - Await.result(future, Defaults.ScenarioTimeout) + Await.result(future, Utils.ScenarioTimeout) logger.info("Scenario finished successfully") 0 } catch { @@ -93,7 +93,7 @@ object Main extends LazyLogging { } try { - Await.result(system.terminate(), Defaults.ActorSystemShutdownTimeout) + Await.result(system.terminate(), Utils.ActorSystemShutdownTimeout) } catch { case e: TimeoutException => logger.warn("Unable to shutdown the actor system within the specified time limit", e) diff --git a/src/main/scala/eu/semberal/dbstress/Orchestrator.scala b/src/main/scala/eu/semberal/dbstress/Orchestrator.scala index d37b9e4..b6fdffa 100644 --- a/src/main/scala/eu/semberal/dbstress/Orchestrator.scala +++ b/src/main/scala/eu/semberal/dbstress/Orchestrator.scala @@ -19,7 +19,7 @@ class Orchestrator(actorSystem: ActorSystem) extends LazyLogging { val controller = actorSystem.actorOf(ControllerActor.props(sc), "controller") - implicit val timeout: Timeout = Defaults.ScenarioTimeout + implicit val timeout: Timeout = Utils.ScenarioTimeout implicit val executionContext = actorSystem.dispatcher val es = new ExportingService(exports) diff --git a/src/main/scala/eu/semberal/dbstress/Utils.scala b/src/main/scala/eu/semberal/dbstress/Utils.scala new file mode 100644 index 0000000..ea8fbaa --- /dev/null +++ b/src/main/scala/eu/semberal/dbstress/Utils.scala @@ -0,0 +1,16 @@ +package eu.semberal.dbstress + +import java.time.format.DateTimeFormatter + +import scala.concurrent.duration.{DurationInt, FiniteDuration} + +object Utils { + val filePathFriendlyDateTimeFormat: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss") + + val ScenarioTimeout: FiniteDuration = (24 * 60 * 60).seconds + + val ActorSystemShutdownTimeout: FiniteDuration = 20.seconds + + def toMillis(start: Long, end: Long): Long = Math.round((end - start) / 1000000.0) + +} diff --git a/src/main/scala/eu/semberal/dbstress/actor/DatabaseActor.scala b/src/main/scala/eu/semberal/dbstress/actor/DatabaseActor.scala index f06403f..38db794 100644 --- a/src/main/scala/eu/semberal/dbstress/actor/DatabaseActor.scala +++ b/src/main/scala/eu/semberal/dbstress/actor/DatabaseActor.scala @@ -1,11 +1,11 @@ package eu.semberal.dbstress.actor import java.sql.{Connection, DriverManager, SQLException} -import java.time.LocalDateTime import akka.actor.{Actor, Props} import akka.event.LoggingReceive import com.typesafe.scalalogging.LazyLogging +import eu.semberal.dbstress.Utils import eu.semberal.dbstress.actor.ControllerActor.{UnitRunError, UnitRunFinished, UnitRunInitializationFailed, UnitRunInitializationFinished} import eu.semberal.dbstress.actor.DatabaseActor.{ConnectionTimeoutException, InitConnection, StartUnitRun} import eu.semberal.dbstress.model.Configuration.UnitRunConfig @@ -35,7 +35,7 @@ class DatabaseActor(scenarioId: String, unitName: String, urConfig: UnitRunConfi override def receive: Receive = LoggingReceive { case InitConnection => val s = sender() - val start = LocalDateTime.now() + val start = System.nanoTime() val future = { val initFuture = Future { @@ -52,11 +52,12 @@ class DatabaseActor(scenarioId: String, unitName: String, urConfig: UnitRunConfi }).getOrElse(initFuture) } + future.onComplete { case Success(c) => s ! UnitRunInitializationFinished this.connection = Some(c) - this.connInitResult = Some(DbConnInitResult(start, LocalDateTime.now())) + this.connInitResult = Some(DbConnInitResult(Utils.toMillis(start, System.nanoTime()))) case Failure(e) => s ! UnitRunInitializationFailed(e) }(systemDispatcher) @@ -69,7 +70,7 @@ class DatabaseActor(scenarioId: String, unitName: String, urConfig: UnitRunConfi prevFuture.flatMap { l => Future { val dbCallId = DbCallId(scenarioId, connectionId, IdGen.genStatementId()) - val start = LocalDateTime.now() + val start = System.nanoTime() connection.map(c => managed(c.createStatement()).map { statement => if (statement.execute(urConfig.dbConfig.query.replace(IdGen.IdPlaceholder, dbCallId.toString))) @@ -78,14 +79,14 @@ class DatabaseActor(scenarioId: String, unitName: String, urConfig: UnitRunConfi UpdateCount(statement.getUpdateCount) }.tried match { case Success(result) => - DbCallSuccess(start, LocalDateTime.now(), dbCallId, result) :: l + DbCallSuccess(Utils.toMillis(start, System.nanoTime()), dbCallId, result) :: l case Failure(e) => logger.warn(s"Query execution failed: ${e.getMessage}") - DbCallFailure(start, LocalDateTime.now(), dbCallId, e) :: l + DbCallFailure(Utils.toMillis(start, System.nanoTime()), dbCallId, e) :: l } ).getOrElse { val e = new IllegalStateException("Connection not initialized") - DbCallFailure(LocalDateTime.now(), LocalDateTime.now(), dbCallId, e) :: l + DbCallFailure(Utils.toMillis(start, System.nanoTime()), dbCallId, e) :: l } }(dbDispatcher) }(systemDispatcher) diff --git a/src/main/scala/eu/semberal/dbstress/model/Results.scala b/src/main/scala/eu/semberal/dbstress/model/Results.scala index cec6d86..4dbf6a8 100644 --- a/src/main/scala/eu/semberal/dbstress/model/Results.scala +++ b/src/main/scala/eu/semberal/dbstress/model/Results.scala @@ -1,21 +1,14 @@ package eu.semberal.dbstress.model -import java.time.LocalDateTime -import java.time.temporal.ChronoUnit - import eu.semberal.dbstress.model.Configuration.UnitConfig object Results { trait OperationResult { - val start: LocalDateTime - - val finish: LocalDateTime - - lazy val duration: Long = ChronoUnit.MILLIS.between(start, finish) + val duration: Long } - case class DbConnInitResult(start: LocalDateTime, finish: LocalDateTime) extends OperationResult + case class DbConnInitResult(duration: Long) extends OperationResult sealed trait DbCallResult extends OperationResult { val dbCallId: DbCallId @@ -25,9 +18,9 @@ object Results { override def toString = s"${scenarioId}_${connectionId}_$statementId" } - case class DbCallSuccess(start: LocalDateTime, finish: LocalDateTime, dbCallId: DbCallId, stmtResult: StatementResult) extends DbCallResult + case class DbCallSuccess(duration: Long, dbCallId: DbCallId, stmtResult: StatementResult) extends DbCallResult - case class DbCallFailure(start: LocalDateTime, finish: LocalDateTime, dbCallId: DbCallId, e: Throwable) extends DbCallResult + case class DbCallFailure(duration: Long, dbCallId: DbCallId, e: Throwable) extends DbCallResult sealed trait StatementResult diff --git a/src/main/scala/eu/semberal/dbstress/util/ResultsExport.scala b/src/main/scala/eu/semberal/dbstress/util/ResultsExport.scala index ac1cf73..d05cc5a 100644 --- a/src/main/scala/eu/semberal/dbstress/util/ResultsExport.scala +++ b/src/main/scala/eu/semberal/dbstress/util/ResultsExport.scala @@ -5,19 +5,18 @@ import java.time.LocalDateTime import com.github.tototoshi.csv.CSVWriter import com.typesafe.scalalogging.LazyLogging -import eu.semberal.dbstress.Defaults._ +import eu.semberal.dbstress.Utils._ import eu.semberal.dbstress.model.Results.ScenarioResult import eu.semberal.dbstress.util.ModelExtensions._ import resource._ trait ResultsExport { - protected val curr = filePathFriendlyDateTimeFormat.format(LocalDateTime.now()) + protected val curr: String = filePathFriendlyDateTimeFormat.format(LocalDateTime.now()) def export(sr: ScenarioResult): Unit protected def withWriter(filePath: String)(op: Writer => Unit): Unit = for (b <- managed(new BufferedWriter(new FileWriter(filePath)))) op(b) - } class CsvResultsExport(outputDir: File) extends ResultsExport with LazyLogging { diff --git a/src/test/scala/eu/semberal/dbstress/model/UnitSummaryTest.scala b/src/test/scala/eu/semberal/dbstress/model/UnitSummaryTest.scala index e390de7..3f24f1e 100644 --- a/src/test/scala/eu/semberal/dbstress/model/UnitSummaryTest.scala +++ b/src/test/scala/eu/semberal/dbstress/model/UnitSummaryTest.scala @@ -1,7 +1,5 @@ package eu.semberal.dbstress.model -import java.time.LocalDateTime - import eu.semberal.dbstress.model.Configuration.{DbCommunicationConfig, UnitConfig, UnitRunConfig} import eu.semberal.dbstress.model.Results._ import eu.semberal.dbstress.model.UnitSummaryTest.unitResult @@ -9,7 +7,7 @@ import org.scalatest.{FlatSpec, Matchers} class UnitSummaryTest extends FlatSpec with Matchers { - val summary = unitResult.summary + private val summary = unitResult.summary behavior of "UnitSummary" @@ -22,13 +20,13 @@ class UnitSummaryTest extends FlatSpec with Matchers { } object UnitSummaryTest { - val repeats = 5 - val parallel = 2 - val unitResult = { + private val repeats = 5 + private val parallel = 2 + private val unitResult = { val dbCommunicationConfig = DbCommunicationConfig("A", Some("B"), "C", "D", "E", Some(10)) - val unitRunResults = UnitRunResult(DbConnInitResult(LocalDateTime.now(), LocalDateTime.now()), List( - DbCallSuccess(LocalDateTime.now(), LocalDateTime.now(), DbCallId("1", "2", "3"), FetchedRows(10)), - DbCallFailure(LocalDateTime.now(), LocalDateTime.now(), DbCallId("4", "5", "6"), new RuntimeException) + val unitRunResults = UnitRunResult(DbConnInitResult(1), List( + DbCallSuccess(1, DbCallId("1", "2", "3"), FetchedRows(10)), + DbCallFailure(2, DbCallId("4", "5", "6"), new RuntimeException) )) UnitResult(UnitConfig("unit1", Some("This is unit1"), UnitRunConfig(dbCommunicationConfig, repeats), parallel), List(unitRunResults)) }