Skip to content

Commit

Permalink
feat: Support adjust the scheduler's tick-duration. (#1366)
Browse files Browse the repository at this point in the history
  • Loading branch information
He-Pin authored Jun 18, 2024
1 parent c254ce9 commit ce9f5a0
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,13 @@ import scala.util.control.NonFatal
import atomic.{ AtomicInteger, AtomicReference }
import scala.annotation.nowarn
import com.typesafe.config.{ Config, ConfigFactory }

import language.postfixOps
import org.scalatest.BeforeAndAfterEach

import org.apache.pekko
import pekko.pattern.ask
import pekko.testkit._
import pekko.util.Helpers

object SchedulerSpec {
val testConfRevolver =
Expand All @@ -40,6 +41,13 @@ object SchedulerSpec {
pekko.scheduler.ticks-per-wheel = 32
""").withFallback(PekkoSpec.testConf)

val testConfAdjustment =
ConfigFactory.parseString("""
pekko.scheduler.implementation = org.apache.pekko.actor.LightArrayRevolverScheduler
pekko.scheduler.tick-duration = 1ns
pekko.scheduler.error-on-tick-duration-verification-failed = off
""").withFallback(PekkoSpec.testConf)

}

trait SchedulerSpec extends BeforeAndAfterEach with DefaultTimeout with ImplicitSender { this: PekkoSpec =>
Expand Down Expand Up @@ -819,3 +827,19 @@ class LightArrayRevolverSchedulerSpec extends PekkoSpec(SchedulerSpec.testConfRe
}

}

class LightArrayRevolverSchedulerAdjustConfigSpec extends PekkoSpec(SchedulerSpec.testConfAdjustment)
with SchedulerSpec {
override def collectCancellable(c: Cancellable): Cancellable = c
private val tickDuration = system.scheduler.asInstanceOf[LightArrayRevolverScheduler].TickDuration

"A LightArrayRevolverScheduler" must {
"be able to adjust the config" in {
if (Helpers.isWindows) {
tickDuration should ===(10.millis)
} else {
tickDuration should ===(1.millis)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class ConfigSpec extends PekkoSpec(ConfigFactory.defaultReference(ActorSystem.fi

getInt("pekko.scheduler.ticks-per-wheel") should ===(512)
getDuration("pekko.scheduler.tick-duration", TimeUnit.MILLISECONDS) should ===(10L)
getBoolean("pekko.scheduler.error-on-tick-duration-verification-failed") should ===(true)
getString("pekko.scheduler.implementation") should ===("org.apache.pekko.actor.LightArrayRevolverScheduler")

getBoolean("pekko.daemonic") should ===(false)
Expand Down
9 changes: 9 additions & 0 deletions actor/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -829,8 +829,17 @@ pekko {
# Note that it might take up to 1 tick to stop the Timer, so setting the
# tick-duration to a high value will make shutting down the actor system
# take longer.
#
# Requirements:
# 1. The minimum supported tick-duration on Windows is 10ms,
# 2. The minimum supported tick-duration is 1ms
tick-duration = 10ms

# An error will be throw when the tick-duration does not meet the requirements.
# When this is set to off, the tick-duration will be adjusted to meet the requirements
# and a warning will be logged.
error-on-tick-duration-verification-failed = on

# The timer uses a circular wheel of buckets to store the timer tasks.
# This should be set such that the majority of scheduled timeouts (for high
# scheduling frequency) will be shorter than one rotation of the wheel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,39 @@ class LightArrayRevolverScheduler(config: Config, log: LoggingAdapter, threadFac
import Helpers.ConfigOps
import Helpers.Requiring

val WheelSize =
val WheelSize: Int =
config
.getInt("pekko.scheduler.ticks-per-wheel")
.requiring(ticks => (ticks & (ticks - 1)) == 0, "ticks-per-wheel must be a power of 2")
val TickDuration =
config
.getMillisDuration("pekko.scheduler.tick-duration")
.requiring(
_ >= 10.millis || !Helpers.isWindows,
"minimum supported pekko.scheduler.tick-duration on Windows is 10ms")
.requiring(_ >= 1.millis, "minimum supported pekko.scheduler.tick-duration is 1ms")
val ShutdownTimeout = config.getMillisDuration("pekko.scheduler.shutdown-timeout")

val TickDuration: FiniteDuration = {
val durationFromConfig = config.getMillisDuration("pekko.scheduler.tick-duration")
val errorOnVerificationFailed = config.getBoolean("pekko.scheduler.error-on-tick-duration-verification-failed")

if (durationFromConfig < 10.millis) {
if (Helpers.isWindows) {
if (errorOnVerificationFailed) {
throw new IllegalArgumentException(
"requirement failed: minimum supported pekko.scheduler.tick-duration on Windows is 10ms")
} else {
log.warning(
"requirement failed: minimum supported pekko.scheduler.tick-duration on Windows is 10ms, adjusted to 10ms now.")
10.millis
}
} else if (durationFromConfig < 1.millis) {
if (errorOnVerificationFailed) {
throw new IllegalArgumentException(
"requirement failed: minimum supported pekko.scheduler.tick-duration is 1ms")
} else {
log.warning(
"requirement failed: minimum supported pekko.scheduler.tick-duration is 1ms, adjusted to 1ms now.")
1.millis
}
} else durationFromConfig
} else durationFromConfig
}

val ShutdownTimeout: FiniteDuration = config.getMillisDuration("pekko.scheduler.shutdown-timeout")

import LightArrayRevolverScheduler._

Expand Down

0 comments on commit ce9f5a0

Please sign in to comment.