This is an automated email from the ASF dual-hosted git repository.

He-Pin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/pekko-persistence-dynamodb.git


The following commit(s) were added to refs/heads/main by this push:
     new 8624c8b  refactor: replace Class.forName with MethodHandles in test 
serializer (#336)
8624c8b is described below

commit 8624c8bda88aced08445af4356647c1f8e031e54
Author: He-Pin(kerr) <[email protected]>
AuthorDate: Tue Jul 7 01:54:30 2026 +0800

    refactor: replace Class.forName with MethodHandles in test serializer (#336)
    
    Motivation:
    Class.forName and reflective constructor calls bypass JIT inlining in the
    test serializer used by the DynamoDB persistence plugin.
    
    Modification:
    - Replace Class.forName with MethodHandles.publicLookup().findConstructor
      for serializer class loading
    - Remove invalid 'final' modifier on local val in WriteThroughputBench
    
    Result:
    JIT-inlinable constructor access in the test serializer path.
    
    Refs #336
---
 .../dynamodb/journal/WriteThroughputBench.scala    | 100 +++++++++++----------
 .../dynamodb/journal/TestSerializer.scala          |   9 +-
 2 files changed, 59 insertions(+), 50 deletions(-)

diff --git 
a/src/test/scala-2/org/apache/pekko/persistence/dynamodb/journal/WriteThroughputBench.scala
 
b/src/test/scala-2/org/apache/pekko/persistence/dynamodb/journal/WriteThroughputBench.scala
index 7023210..bdeedee 100644
--- 
a/src/test/scala-2/org/apache/pekko/persistence/dynamodb/journal/WriteThroughputBench.scala
+++ 
b/src/test/scala-2/org/apache/pekko/persistence/dynamodb/journal/WriteThroughputBench.scala
@@ -27,10 +27,52 @@ import java.util.concurrent.ThreadLocalRandom
 import scala.concurrent.duration._
 
 object WriteThroughputBench extends DynamoDBUtils {
+
+  private lazy val config =
+    ConfigFactory
+      .systemProperties()
+      .withFallback(
+        ConfigFactory
+          .parseString("""
+my-dynamodb-journal {
+  journal-table = "WriteThroughputBench"
+  endpoint = ${?AWS_DYNAMODB_ENDPOINT}
+  aws-access-key-id = ${?AWS_ACCESS_KEY_ID}
+  aws-secret-access-key = ${?AWS_SECRET_ACCESS_KEY}
+  aws-client-config {
+    max-connections = 100
+  }
+  plugin-dispatcher = "dispatcher"
+  replay-dispatcher = "dispatcher"
+  client-dispatcher = "dispatcher"
+}
+dispatcher {
+  type = Dispatcher
+  executor = "fork-join-executor"
+  fork-join-executor {
+    parallelism-min = 4
+    parallelism-max = 8
+  }
+}
+pekko.actor.default-dispatcher.fork-join-executor.parallelism-max = 4
+writers = 1000
+writer-dispatcher {
+  type = Dispatcher
+  executor = "fork-join-executor"
+  fork-join-executor {
+    parallelism-min = 2
+    parallelism-max = 2
+  }
+}
+""").resolve)
+      .withFallback(ConfigFactory.load())
+
+  lazy val system: ActorSystem = ActorSystem("WriteThroughputBench", config)
+
   def main(args: Array[String]): Unit = {
 
     def rnd = ThreadLocalRandom.current()
-    final val oneBillion = 1000L * 1000 * 1000
+    val oneBillion = 1000L * 1000 * 1000
 
     class H private (private val entries: Map[Int, Int]) {
       def this(i: Int) = this(Map(i -> 1))
@@ -89,46 +131,6 @@ object WriteThroughputBench extends DynamoDBUtils {
       def receiveRecover = Actor.emptyBehavior
     }
 
-    val config =
-      ConfigFactory
-        .systemProperties()
-        .withFallback(
-          ConfigFactory
-            .parseString("""
-my-dynamodb-journal {
-  journal-table = "WriteThroughputBench"
-  endpoint = ${?AWS_DYNAMODB_ENDPOINT}
-  aws-access-key-id = ${?AWS_ACCESS_KEY_ID}
-  aws-secret-access-key = ${?AWS_SECRET_ACCESS_KEY}
-  aws-client-config {
-    max-connections = 100
-  }
-  plugin-dispatcher = "dispatcher"
-  replay-dispatcher = "dispatcher"
-  client-dispatcher = "dispatcher"
-}
-dispatcher {
-  type = Dispatcher
-  executor = "fork-join-executor"
-  fork-join-executor {
-    parallelism-min = 4
-    parallelism-max = 8
-  }
-}
-pekko.actor.default-dispatcher.fork-join-executor.parallelism-max = 4
-writers = 1000
-writer-dispatcher {
-  type = Dispatcher
-  executor = "fork-join-executor"
-  fork-join-executor {
-    parallelism-min = 2
-    parallelism-max = 2
-  }
-}
-""").resolve)
-        .withFallback(ConfigFactory.load())
-
-    implicit val system: ActorSystem = ActorSystem("WriteThroughputBench", 
config)
     implicit val materializer: Materializer = Materializer(system)
 
     /*
@@ -169,6 +171,14 @@ writer-dispatcher {
       .expand(Iterator.continually(_))
       .withAttributes(Attributes.asyncBoundary)
 
+    def printStats(r: Report): Unit = {
+      def p(h: Histogram, pc: Double) = h.getValueAtPercentile(pc) / 1000000d
+      def perc(h: Histogram) =
+        f"50=${p(h, 0.5)}%5.1f 90=${p(h, 0.9)}%5.1f 99=${p(h, 0.99)}%5.1f 
99.9=${p(h, 0.999)}%5.1f 99.99=${p(h, 0.9999)}%5.1f"
+      println(f"count ${r.endToEnd.getTotalCount}%6d/s  percentiles: 
endToEnd(${perc(r.endToEnd)}) calls(${perc(
+          r.calls)}) retries: ${r.retries}")
+    }
+
     val (eRef, cRef) =
       RunnableGraph
         .fromGraph(GraphDSL.createGraph(endToEnd, calls)(Keep.both) { implicit 
b => (e, c) =>
@@ -193,13 +203,5 @@ writer-dispatcher {
 
     system.terminate()
     dynamo.shutdown()
-
-    def printStats(r: Report): Unit = {
-      def p(h: Histogram, pc: Double) = h.getValueAtPercentile(pc) / 1000000d
-      def perc(h: Histogram) =
-        f"50=${p(h, 0.5)}%5.1f 90=${p(h, 0.9)}%5.1f 99=${p(h, 0.99)}%5.1f 
99.9=${p(h, 0.999)}%5.1f 99.99=${p(h, 0.9999)}%5.1f"
-      println(f"count ${r.endToEnd.getTotalCount}%6d/s  percentiles: 
endToEnd(${perc(r.endToEnd)}) calls(${perc(
-          r.calls)}) retries: ${r.retries}")
-    }
   }
 }
diff --git 
a/src/test/scala/org/apache/pekko/persistence/dynamodb/journal/TestSerializer.scala
 
b/src/test/scala/org/apache/pekko/persistence/dynamodb/journal/TestSerializer.scala
index 766a836..ff16e6a 100644
--- 
a/src/test/scala/org/apache/pekko/persistence/dynamodb/journal/TestSerializer.scala
+++ 
b/src/test/scala/org/apache/pekko/persistence/dynamodb/journal/TestSerializer.scala
@@ -13,6 +13,8 @@
 
 package org.apache.pekko.persistence.dynamodb.journal
 
+import java.lang.invoke.MethodHandles
+
 import org.apache.pekko.actor.ExtendedActorSystem
 import org.apache.pekko.serialization.{ AsyncSerializerWithStringManifest, 
JavaSerializer }
 
@@ -29,7 +31,12 @@ class TestSerializer(system: ExtendedActorSystem) extends 
AsyncSerializerWithStr
   val javaSerializer: JavaSerializer = new JavaSerializer(system)
 
   override def fromBinaryAsync(bytes: Array[Byte], manifest: String): 
Future[AnyRef] =
-    Future.successful(javaSerializer.fromBinary(bytes, 
Class.forName(manifest)))
+    Future.successful {
+      val lookup = MethodHandles.lookup()
+      val clazz = lookup.findClass(manifest)
+      lookup.ensureInitialized(clazz)
+      javaSerializer.fromBinary(bytes, clazz)
+    }
 
   override def toBinaryAsync(obj: AnyRef): Future[Array[Byte]] =
     Future.successful(javaSerializer.toBinary(obj))


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to