Skip to content

Commit

Permalink
stub of JEP 356 generator
Browse files Browse the repository at this point in the history
  • Loading branch information
pjfanning committed Jan 30, 2025
1 parent e4fda5f commit a51d31b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 1 deletion.
8 changes: 8 additions & 0 deletions actor/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -1396,4 +1396,12 @@ pekko {
}
#//#circuit-breaker-default

random {
# The default random number generator used by the Pekko library.
# This setting does not affect SecureRandom use cases.
# Valid options are listed in
# https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/random/package-summary.html#algorithms
generator-implementation = "ThreadLocalRandom"
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ package org.apache.pekko.util
import org.apache.pekko
import pekko.annotation.InternalApi

import com.typesafe.config.ConfigFactory

import java.lang.invoke.{ MethodHandles, MethodType }
import java.util.concurrent.ThreadLocalRandom

@InternalApi
Expand All @@ -40,7 +43,41 @@ private[pekko] object ThreadLocalRandomNumberGenerator extends RandomNumberGener
override def nextDouble(): Double = ThreadLocalRandom.current().nextDouble()
}

// https://openjdk.org/jeps/356
@InternalApi
private[pekko] class Jep356RandomNumberGenerator(impl: String) extends RandomNumberGenerator {

private val rngClass = Class.forName("java.util.random.RandomGenerator")
private val lookup = MethodHandles.publicLookup()
private val createHandle = lookup.findStatic(rngClass, "of", MethodType.methodType(rngClass, classOf[String]))
private val intHandle = lookup.findVirtual(rngClass, "nextInt", MethodType.methodType(classOf[Int]))
private val intBoundHandle =
lookup.findVirtual(rngClass, "nextInt", MethodType.methodType(classOf[Int], classOf[Int]))
private val longHandle = lookup.findVirtual(rngClass, "nextLong", MethodType.methodType(classOf[Long]))
private val doubleHandle = lookup.findVirtual(rngClass, "nextDouble", MethodType.methodType(classOf[Double]))
private val rng = createHandle.invoke(impl)

override def nextInt(): Int = intHandle.invoke(rng)
override def nextInt(bound: Int): Int = intBoundHandle.invoke(rng, bound)
override def nextInt(origin: Int, bound: Int): Int = {
if (origin >= bound)
throw new IllegalArgumentException("origin must be less than bound")
nextInt(bound - origin) + origin
}
override def nextLong(): Long = longHandle.invoke(rng)
override def nextDouble(): Double = doubleHandle.invoke(rng)
}

@InternalApi
private[pekko] object RandomNumberGenerator {
def get(): RandomNumberGenerator = ThreadLocalRandomNumberGenerator

private val generator = {
val cfg = ConfigFactory.load()
cfg.getString("pekko.random.generator-implementation") match {
case "ThreadLocalRandom" => ThreadLocalRandomNumberGenerator
case impl => new Jep356RandomNumberGenerator(impl)
}
}

def get(): RandomNumberGenerator = generator
}

0 comments on commit a51d31b

Please sign in to comment.