+tes introduce simple way to gather flamegraphs from multinode specs
This commit is contained in:
parent
b6a94e1758
commit
7c79b40dea
3 changed files with 70 additions and 5 deletions
|
|
@ -5,15 +5,18 @@ package akka.remote.testkit
|
|||
|
||||
import language.implicitConversions
|
||||
import java.net.{ InetAddress, InetSocketAddress }
|
||||
import com.typesafe.config.{ ConfigObject, ConfigFactory, Config }
|
||||
import scala.concurrent.{ Await, Awaitable }
|
||||
|
||||
import com.typesafe.config.{ Config, ConfigFactory, ConfigObject }
|
||||
|
||||
import scala.concurrent.{ Await, Awaitable, Future }
|
||||
import scala.util.control.NonFatal
|
||||
import scala.collection.immutable
|
||||
import akka.actor._
|
||||
import akka.util.Timeout
|
||||
import akka.remote.testconductor.{ TestConductorExt, TestConductor, RoleName }
|
||||
import akka.remote.testconductor.{ RoleName, TestConductor, TestConductorExt }
|
||||
import akka.testkit._
|
||||
import akka.testkit.TestEvent._
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import akka.remote.testconductor.RoleName
|
||||
import akka.actor.RootActorPath
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (C) 2016 Lightbend Inc. <http://www.lightbend.com>
|
||||
*/
|
||||
|
||||
package akka.remote.testkit
|
||||
|
||||
import java.io.File
|
||||
|
||||
import akka.remote.testconductor.RoleName
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.duration._
|
||||
|
||||
/**
|
||||
* INTERNAL API: Support trait allowing trivially recording perf metrics from [[MultiNodeSpec]]s
|
||||
*/
|
||||
private[akka] trait PerfFlamesSupport { _: MultiNodeSpec ⇒
|
||||
|
||||
/**
|
||||
* Runs `perf-java-flames` script on given node (JVM process).
|
||||
* Refer to https://github.com/jrudolph/perf-map-agent for options and manual.
|
||||
*
|
||||
* Options are currently to be passed in via `export PERF_MAP_OPTIONS` etc.
|
||||
*/
|
||||
def runPerfFlames(nodes: RoleName*)(delay: FiniteDuration, time: FiniteDuration = 15.seconds): Unit = {
|
||||
if (isPerfJavaFlamesAvailable && isNode(nodes: _*)) {
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
|
||||
val afterDelay = akka.pattern.after(delay, system.scheduler)(Future.successful("GO!"))
|
||||
afterDelay onComplete { it ⇒
|
||||
import java.lang.management._
|
||||
val name = ManagementFactory.getRuntimeMXBean.getName
|
||||
val pid = name.substring(0, name.indexOf('@')).toInt
|
||||
|
||||
val perfCommand = s"$perfJavaFlamesPath $pid"
|
||||
println(s"[perf @ $myself($pid)][OUT]: " + perfCommand)
|
||||
|
||||
import scala.sys.process._
|
||||
perfCommand.run(new ProcessLogger {
|
||||
override def buffer[T](f: ⇒ T): T = f
|
||||
override def out(s: ⇒ String): Unit = println(s"[perf @ $myself($pid)][OUT] " + s)
|
||||
override def err(s: ⇒ String): Unit = println(s"[perf @ $myself($pid)][ERR] " + s)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def perfJavaFlamesPath: String =
|
||||
"/home/ubuntu/perf-java-flames"
|
||||
|
||||
def isPerfJavaFlamesAvailable: Boolean = {
|
||||
val isIt = new File(perfJavaFlamesPath).exists()
|
||||
if (!isIt) println(s"WARN: perf-java-flames not available under [$perfJavaFlamesPath]! Skipping perf profiling.")
|
||||
isIt
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -6,13 +6,14 @@ package akka.remote.artery
|
|||
import java.nio.ByteBuffer
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit.NANOSECONDS
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import scala.concurrent.duration._
|
||||
import akka.actor._
|
||||
import akka.remote.RemoteActorRefProvider
|
||||
import akka.remote.testconductor.RoleName
|
||||
import akka.remote.testkit.MultiNodeConfig
|
||||
import akka.remote.testkit.MultiNodeSpec
|
||||
import akka.remote.testkit.PerfFlamesSupport
|
||||
import akka.remote.testkit.STMultiNodeSpec
|
||||
import akka.serialization.ByteBufferSerializer
|
||||
import akka.serialization.SerializerWithStringManifest
|
||||
|
|
@ -199,7 +200,8 @@ class MaxThroughputSpecMultiJvmNode2 extends MaxThroughputSpec
|
|||
|
||||
abstract class MaxThroughputSpec
|
||||
extends MultiNodeSpec(MaxThroughputSpec)
|
||||
with STMultiNodeSpec with ImplicitSender {
|
||||
with STMultiNodeSpec with ImplicitSender
|
||||
with PerfFlamesSupport {
|
||||
|
||||
import MaxThroughputSpec._
|
||||
|
||||
|
|
@ -269,6 +271,8 @@ abstract class MaxThroughputSpec
|
|||
import testSettings._
|
||||
val receiverName = testName + "-rcv"
|
||||
|
||||
runPerfFlames(first, second)(delay = 5.seconds, time = 15.seconds)
|
||||
|
||||
runOn(second) {
|
||||
val rep = reporter(testName)
|
||||
for (n ← 1 to senderReceiverPairs) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue