Introduce new default entity passivation strategy (#30968)
This commit is contained in:
parent
35c128b7d8
commit
3a7201183d
11 changed files with 673 additions and 688 deletions
|
|
@ -165,89 +165,90 @@ object ClusterShardingSettings {
|
||||||
|
|
||||||
@ApiMayChange
|
@ApiMayChange
|
||||||
final class PassivationStrategySettings private (
|
final class PassivationStrategySettings private (
|
||||||
val strategy: String,
|
val idleEntitySettings: Option[PassivationStrategySettings.IdleSettings],
|
||||||
val idleSettings: PassivationStrategySettings.IdleSettings,
|
val activeEntityLimit: Option[Int],
|
||||||
val leastRecentlyUsedSettings: PassivationStrategySettings.LeastRecentlyUsedSettings,
|
val replacementPolicySettings: Option[PassivationStrategySettings.PolicySettings],
|
||||||
val mostRecentlyUsedSettings: PassivationStrategySettings.MostRecentlyUsedSettings,
|
|
||||||
val leastFrequentlyUsedSettings: PassivationStrategySettings.LeastFrequentlyUsedSettings,
|
|
||||||
private[akka] val oldSettingUsed: Boolean) {
|
private[akka] val oldSettingUsed: Boolean) {
|
||||||
|
|
||||||
def this(
|
def this(
|
||||||
strategy: String,
|
idleEntitySettings: Option[PassivationStrategySettings.IdleSettings],
|
||||||
idleSettings: PassivationStrategySettings.IdleSettings,
|
activeEntityLimit: Option[Int],
|
||||||
leastRecentlyUsedSettings: PassivationStrategySettings.LeastRecentlyUsedSettings,
|
replacementPolicySettings: Option[PassivationStrategySettings.PolicySettings]) =
|
||||||
mostRecentlyUsedSettings: PassivationStrategySettings.MostRecentlyUsedSettings,
|
this(idleEntitySettings, activeEntityLimit, replacementPolicySettings, oldSettingUsed = false)
|
||||||
leastFrequentlyUsedSettings: PassivationStrategySettings.LeastFrequentlyUsedSettings) =
|
|
||||||
this(
|
|
||||||
strategy,
|
|
||||||
idleSettings,
|
|
||||||
leastRecentlyUsedSettings,
|
|
||||||
mostRecentlyUsedSettings,
|
|
||||||
leastFrequentlyUsedSettings,
|
|
||||||
oldSettingUsed = false)
|
|
||||||
|
|
||||||
import PassivationStrategySettings._
|
import PassivationStrategySettings._
|
||||||
|
|
||||||
def withIdleStrategy(settings: IdleSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(settings: IdleSettings): PassivationStrategySettings =
|
||||||
copy(strategy = "idle", idleSettings = settings, oldSettingUsed = false)
|
copy(idleEntitySettings = Some(settings), oldSettingUsed = false)
|
||||||
|
|
||||||
def withLeastRecentlyUsedStrategy(settings: LeastRecentlyUsedSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(timeout: FiniteDuration): PassivationStrategySettings =
|
||||||
copy(strategy = "least-recently-used", leastRecentlyUsedSettings = settings)
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout))
|
||||||
|
|
||||||
def withMostRecentlyUsedStrategy(settings: MostRecentlyUsedSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(timeout: FiniteDuration, interval: FiniteDuration): PassivationStrategySettings =
|
||||||
copy(strategy = "most-recently-used", mostRecentlyUsedSettings = settings)
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout).withInterval(interval))
|
||||||
|
|
||||||
def withLeastFrequentlyUsedStrategy(settings: LeastFrequentlyUsedSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(timeout: java.time.Duration): PassivationStrategySettings =
|
||||||
copy(strategy = "least-frequently-used", leastFrequentlyUsedSettings = settings)
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout))
|
||||||
|
|
||||||
|
def withIdleEntityPassivation(
|
||||||
|
timeout: java.time.Duration,
|
||||||
|
interval: java.time.Duration): PassivationStrategySettings =
|
||||||
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout).withInterval(interval))
|
||||||
|
|
||||||
|
def withActiveEntityLimit(limit: Int): PassivationStrategySettings =
|
||||||
|
copy(activeEntityLimit = Some(limit))
|
||||||
|
|
||||||
|
def withReplacementPolicy(settings: PolicySettings): PassivationStrategySettings =
|
||||||
|
copy(replacementPolicySettings = Some(settings))
|
||||||
|
|
||||||
|
def withLeastRecentlyUsedReplacement(): PassivationStrategySettings =
|
||||||
|
withReplacementPolicy(LeastRecentlyUsedSettings.defaults)
|
||||||
|
|
||||||
|
def withMostRecentlyUsedReplacement(): PassivationStrategySettings =
|
||||||
|
withReplacementPolicy(MostRecentlyUsedSettings.defaults)
|
||||||
|
|
||||||
|
def withLeastFrequentlyUsedReplacement(): PassivationStrategySettings =
|
||||||
|
withReplacementPolicy(LeastFrequentlyUsedSettings.defaults)
|
||||||
|
|
||||||
private[akka] def withOldIdleStrategy(timeout: FiniteDuration): PassivationStrategySettings =
|
private[akka] def withOldIdleStrategy(timeout: FiniteDuration): PassivationStrategySettings =
|
||||||
copy(strategy = "idle", idleSettings = idleSettings.withTimeout(timeout), oldSettingUsed = true)
|
copy(
|
||||||
|
idleEntitySettings = Some(new IdleSettings(timeout, None)),
|
||||||
|
activeEntityLimit = None,
|
||||||
|
replacementPolicySettings = None,
|
||||||
|
oldSettingUsed = true)
|
||||||
|
|
||||||
private def copy(
|
private def copy(
|
||||||
strategy: String,
|
idleEntitySettings: Option[IdleSettings] = idleEntitySettings,
|
||||||
idleSettings: IdleSettings = idleSettings,
|
activeEntityLimit: Option[Int] = activeEntityLimit,
|
||||||
leastRecentlyUsedSettings: LeastRecentlyUsedSettings = leastRecentlyUsedSettings,
|
replacementPolicySettings: Option[PolicySettings] = replacementPolicySettings,
|
||||||
mostRecentlyUsedSettings: MostRecentlyUsedSettings = mostRecentlyUsedSettings,
|
|
||||||
leastFrequentlyUsedSettings: LeastFrequentlyUsedSettings = leastFrequentlyUsedSettings,
|
|
||||||
oldSettingUsed: Boolean = oldSettingUsed): PassivationStrategySettings =
|
oldSettingUsed: Boolean = oldSettingUsed): PassivationStrategySettings =
|
||||||
new PassivationStrategySettings(
|
new PassivationStrategySettings(idleEntitySettings, activeEntityLimit, replacementPolicySettings, oldSettingUsed)
|
||||||
strategy,
|
|
||||||
idleSettings,
|
|
||||||
leastRecentlyUsedSettings,
|
|
||||||
mostRecentlyUsedSettings,
|
|
||||||
leastFrequentlyUsedSettings,
|
|
||||||
oldSettingUsed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object PassivationStrategySettings {
|
object PassivationStrategySettings {
|
||||||
import ClassicShardingSettings.{ PassivationStrategySettings => ClassicPassivationStrategySettings }
|
import ClassicShardingSettings.{ PassivationStrategySettings => ClassicPassivationStrategySettings }
|
||||||
|
|
||||||
val defaults = new PassivationStrategySettings(
|
val defaults = new PassivationStrategySettings(
|
||||||
strategy = "idle",
|
idleEntitySettings = None,
|
||||||
IdleSettings.defaults,
|
activeEntityLimit = None,
|
||||||
LeastRecentlyUsedSettings.defaults,
|
replacementPolicySettings = None,
|
||||||
MostRecentlyUsedSettings.defaults,
|
|
||||||
LeastFrequentlyUsedSettings.defaults,
|
|
||||||
oldSettingUsed = false)
|
oldSettingUsed = false)
|
||||||
|
|
||||||
val disabled: PassivationStrategySettings = defaults.copy(strategy = "none")
|
val disabled: PassivationStrategySettings = defaults
|
||||||
|
|
||||||
def apply(classic: ClassicShardingSettings.PassivationStrategySettings) =
|
def apply(classic: ClassicShardingSettings.PassivationStrategySettings) =
|
||||||
new PassivationStrategySettings(
|
new PassivationStrategySettings(
|
||||||
classic.strategy,
|
classic.idleEntitySettings.map(IdleSettings.apply),
|
||||||
IdleSettings(classic.idleSettings),
|
classic.activeEntityLimit,
|
||||||
LeastRecentlyUsedSettings(classic.leastRecentlyUsedSettings),
|
classic.replacementPolicySettings.map(PolicySettings.apply),
|
||||||
MostRecentlyUsedSettings(classic.mostRecentlyUsedSettings),
|
|
||||||
LeastFrequentlyUsedSettings(classic.leastFrequentlyUsedSettings),
|
|
||||||
classic.oldSettingUsed)
|
classic.oldSettingUsed)
|
||||||
|
|
||||||
def toClassic(settings: PassivationStrategySettings): ClassicPassivationStrategySettings =
|
def toClassic(settings: PassivationStrategySettings): ClassicPassivationStrategySettings =
|
||||||
new ClassicPassivationStrategySettings(
|
new ClassicPassivationStrategySettings(
|
||||||
strategy = settings.strategy,
|
settings.idleEntitySettings.map(IdleSettings.toClassic),
|
||||||
IdleSettings.toClassic(settings.idleSettings),
|
settings.activeEntityLimit,
|
||||||
LeastRecentlyUsedSettings.toClassic(settings.leastRecentlyUsedSettings),
|
settings.replacementPolicySettings.map(PolicySettings.toClassic),
|
||||||
MostRecentlyUsedSettings.toClassic(settings.mostRecentlyUsedSettings),
|
settings.oldSettingUsed)
|
||||||
LeastFrequentlyUsedSettings.toClassic(settings.leastFrequentlyUsedSettings))
|
|
||||||
|
|
||||||
object IdleSettings {
|
object IdleSettings {
|
||||||
val defaults: IdleSettings = new IdleSettings(timeout = 2.minutes, interval = None)
|
val defaults: IdleSettings = new IdleSettings(timeout = 2.minutes, interval = None)
|
||||||
|
|
@ -273,21 +274,34 @@ object ClusterShardingSettings {
|
||||||
new IdleSettings(timeout, interval)
|
new IdleSettings(timeout, interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object PolicySettings {
|
||||||
|
def apply(classic: ClassicPassivationStrategySettings.PolicySettings): PolicySettings = classic match {
|
||||||
|
case classic: ClassicPassivationStrategySettings.LeastRecentlyUsedSettings =>
|
||||||
|
LeastRecentlyUsedSettings(classic)
|
||||||
|
case classic: ClassicPassivationStrategySettings.MostRecentlyUsedSettings =>
|
||||||
|
MostRecentlyUsedSettings(classic)
|
||||||
|
case classic: ClassicPassivationStrategySettings.LeastFrequentlyUsedSettings =>
|
||||||
|
LeastFrequentlyUsedSettings(classic)
|
||||||
|
}
|
||||||
|
|
||||||
|
def toClassic(settings: PolicySettings): ClassicPassivationStrategySettings.PolicySettings = settings match {
|
||||||
|
case settings: LeastRecentlyUsedSettings => LeastRecentlyUsedSettings.toClassic(settings)
|
||||||
|
case settings: MostRecentlyUsedSettings => MostRecentlyUsedSettings.toClassic(settings)
|
||||||
|
case settings: LeastFrequentlyUsedSettings => LeastFrequentlyUsedSettings.toClassic(settings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed trait PolicySettings
|
||||||
|
|
||||||
object LeastRecentlyUsedSettings {
|
object LeastRecentlyUsedSettings {
|
||||||
val defaults: LeastRecentlyUsedSettings =
|
val defaults: LeastRecentlyUsedSettings = new LeastRecentlyUsedSettings(segmentedSettings = None)
|
||||||
new LeastRecentlyUsedSettings(limit = 100000, segmentedSettings = None, idleSettings = None)
|
|
||||||
|
|
||||||
def apply(classic: ClassicPassivationStrategySettings.LeastRecentlyUsedSettings): LeastRecentlyUsedSettings =
|
def apply(classic: ClassicPassivationStrategySettings.LeastRecentlyUsedSettings): LeastRecentlyUsedSettings =
|
||||||
new LeastRecentlyUsedSettings(
|
new LeastRecentlyUsedSettings(classic.segmentedSettings.map(SegmentedSettings.apply))
|
||||||
classic.limit,
|
|
||||||
classic.segmentedSettings.map(SegmentedSettings.apply),
|
|
||||||
classic.idleSettings.map(IdleSettings.apply))
|
|
||||||
|
|
||||||
def toClassic(settings: LeastRecentlyUsedSettings): ClassicPassivationStrategySettings.LeastRecentlyUsedSettings =
|
def toClassic(settings: LeastRecentlyUsedSettings): ClassicPassivationStrategySettings.LeastRecentlyUsedSettings =
|
||||||
new ClassicPassivationStrategySettings.LeastRecentlyUsedSettings(
|
new ClassicPassivationStrategySettings.LeastRecentlyUsedSettings(
|
||||||
settings.limit,
|
settings.segmentedSettings.map(SegmentedSettings.toClassic))
|
||||||
settings.segmentedSettings.map(SegmentedSettings.toClassic),
|
|
||||||
settings.idleSettings.map(IdleSettings.toClassic))
|
|
||||||
|
|
||||||
object SegmentedSettings {
|
object SegmentedSettings {
|
||||||
def apply(classic: ClassicPassivationStrategySettings.LeastRecentlyUsedSettings.SegmentedSettings)
|
def apply(classic: ClassicPassivationStrategySettings.LeastRecentlyUsedSettings.SegmentedSettings)
|
||||||
|
|
@ -315,122 +329,58 @@ object ClusterShardingSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class LeastRecentlyUsedSettings(
|
final class LeastRecentlyUsedSettings(val segmentedSettings: Option[LeastRecentlyUsedSettings.SegmentedSettings])
|
||||||
val limit: Int,
|
extends PolicySettings {
|
||||||
val segmentedSettings: Option[LeastRecentlyUsedSettings.SegmentedSettings],
|
import LeastRecentlyUsedSettings.SegmentedSettings
|
||||||
val idleSettings: Option[IdleSettings]) {
|
|
||||||
|
|
||||||
def withLimit(limit: Int): LeastRecentlyUsedSettings = copy(limit = limit)
|
def withSegmented(levels: Int): LeastRecentlyUsedSettings =
|
||||||
|
copy(segmentedSettings = Some(new SegmentedSettings(levels, Nil)))
|
||||||
|
|
||||||
def withSegmented(levels: Int): LeastRecentlyUsedSettings = withSegmented(levels, Nil)
|
def withSegmented(proportions: immutable.Seq[Double]): LeastRecentlyUsedSettings =
|
||||||
|
copy(segmentedSettings = Some(new SegmentedSettings(proportions.size, proportions)))
|
||||||
|
|
||||||
def withSegmented(levels: Int, proportions: immutable.Seq[Double]): LeastRecentlyUsedSettings =
|
def withSegmentedProportions(proportions: java.util.List[java.lang.Double]): LeastRecentlyUsedSettings =
|
||||||
copy(segmentedSettings = Some(new LeastRecentlyUsedSettings.SegmentedSettings(levels, proportions)))
|
withSegmented(immutableSeq(proportions).map(_.toDouble))
|
||||||
|
|
||||||
def withSegmentedProportions(
|
private def copy(segmentedSettings: Option[SegmentedSettings]): LeastRecentlyUsedSettings =
|
||||||
levels: Int,
|
new LeastRecentlyUsedSettings(segmentedSettings)
|
||||||
proportions: java.util.List[java.lang.Double]): LeastRecentlyUsedSettings =
|
|
||||||
withSegmented(levels, immutableSeq(proportions).map(_.toDouble))
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration): LeastRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, None)))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration): LeastRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration, interval: FiniteDuration): LeastRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, Some(interval))))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration, interval: java.time.Duration): LeastRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala, interval.asScala)
|
|
||||||
|
|
||||||
private def copy(
|
|
||||||
limit: Int = limit,
|
|
||||||
segmentedSettings: Option[LeastRecentlyUsedSettings.SegmentedSettings] = segmentedSettings,
|
|
||||||
idleSettings: Option[IdleSettings] = idleSettings): LeastRecentlyUsedSettings =
|
|
||||||
new LeastRecentlyUsedSettings(limit, segmentedSettings, idleSettings)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object MostRecentlyUsedSettings {
|
object MostRecentlyUsedSettings {
|
||||||
val defaults: MostRecentlyUsedSettings = new MostRecentlyUsedSettings(limit = 100000, idleSettings = None)
|
val defaults: MostRecentlyUsedSettings = new MostRecentlyUsedSettings
|
||||||
|
|
||||||
def apply(classic: ClassicPassivationStrategySettings.MostRecentlyUsedSettings): MostRecentlyUsedSettings =
|
def apply(classic: ClassicPassivationStrategySettings.MostRecentlyUsedSettings): MostRecentlyUsedSettings = {
|
||||||
new MostRecentlyUsedSettings(classic.limit, classic.idleSettings.map(IdleSettings.apply))
|
val _ = classic // currently not used
|
||||||
|
new MostRecentlyUsedSettings
|
||||||
|
}
|
||||||
|
|
||||||
def toClassic(settings: MostRecentlyUsedSettings): ClassicPassivationStrategySettings.MostRecentlyUsedSettings =
|
def toClassic(settings: MostRecentlyUsedSettings): ClassicPassivationStrategySettings.MostRecentlyUsedSettings = {
|
||||||
new ClassicPassivationStrategySettings.MostRecentlyUsedSettings(
|
val _ = settings // currently not used
|
||||||
settings.limit,
|
new ClassicPassivationStrategySettings.MostRecentlyUsedSettings
|
||||||
settings.idleSettings.map(IdleSettings.toClassic))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class MostRecentlyUsedSettings(val limit: Int, val idleSettings: Option[IdleSettings]) {
|
final class MostRecentlyUsedSettings extends PolicySettings
|
||||||
|
|
||||||
def withLimit(limit: Int): MostRecentlyUsedSettings = copy(limit = limit)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration): MostRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, None)))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration): MostRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration, interval: FiniteDuration): MostRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, Some(interval))))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration, interval: java.time.Duration): MostRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala, interval.asScala)
|
|
||||||
|
|
||||||
private def copy(
|
|
||||||
limit: Int = limit,
|
|
||||||
idleSettings: Option[IdleSettings] = idleSettings): MostRecentlyUsedSettings =
|
|
||||||
new MostRecentlyUsedSettings(limit, idleSettings)
|
|
||||||
}
|
|
||||||
|
|
||||||
object LeastFrequentlyUsedSettings {
|
object LeastFrequentlyUsedSettings {
|
||||||
val defaults: LeastFrequentlyUsedSettings =
|
val defaults: LeastFrequentlyUsedSettings = new LeastFrequentlyUsedSettings(dynamicAging = false)
|
||||||
new LeastFrequentlyUsedSettings(limit = 100000, dynamicAging = false, idleSettings = None)
|
|
||||||
|
|
||||||
def apply(classic: ClassicPassivationStrategySettings.LeastFrequentlyUsedSettings): LeastFrequentlyUsedSettings =
|
def apply(classic: ClassicPassivationStrategySettings.LeastFrequentlyUsedSettings): LeastFrequentlyUsedSettings =
|
||||||
new LeastFrequentlyUsedSettings(
|
new LeastFrequentlyUsedSettings(classic.dynamicAging)
|
||||||
classic.limit,
|
|
||||||
classic.dynamicAging,
|
|
||||||
classic.idleSettings.map(IdleSettings.apply))
|
|
||||||
|
|
||||||
def toClassic(
|
def toClassic(
|
||||||
settings: LeastFrequentlyUsedSettings): ClassicPassivationStrategySettings.LeastFrequentlyUsedSettings =
|
settings: LeastFrequentlyUsedSettings): ClassicPassivationStrategySettings.LeastFrequentlyUsedSettings =
|
||||||
new ClassicPassivationStrategySettings.LeastFrequentlyUsedSettings(
|
new ClassicPassivationStrategySettings.LeastFrequentlyUsedSettings(settings.dynamicAging)
|
||||||
settings.limit,
|
|
||||||
settings.dynamicAging,
|
|
||||||
settings.idleSettings.map(IdleSettings.toClassic))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final class LeastFrequentlyUsedSettings(
|
final class LeastFrequentlyUsedSettings(val dynamicAging: Boolean) extends PolicySettings {
|
||||||
val limit: Int,
|
|
||||||
val dynamicAging: Boolean,
|
|
||||||
val idleSettings: Option[IdleSettings]) {
|
|
||||||
|
|
||||||
def withLimit(limit: Int): LeastFrequentlyUsedSettings = copy(limit = limit)
|
|
||||||
|
|
||||||
def withDynamicAging(): LeastFrequentlyUsedSettings = withDynamicAging(enabled = true)
|
def withDynamicAging(): LeastFrequentlyUsedSettings = withDynamicAging(enabled = true)
|
||||||
|
|
||||||
def withDynamicAging(enabled: Boolean): LeastFrequentlyUsedSettings = copy(dynamicAging = enabled)
|
def withDynamicAging(enabled: Boolean): LeastFrequentlyUsedSettings = copy(dynamicAging = enabled)
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration): LeastFrequentlyUsedSettings =
|
private def copy(dynamicAging: Boolean): LeastFrequentlyUsedSettings =
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, None)))
|
new LeastFrequentlyUsedSettings(dynamicAging)
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration): LeastFrequentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration, interval: FiniteDuration): LeastFrequentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, Some(interval))))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration, interval: java.time.Duration): LeastFrequentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala, interval.asScala)
|
|
||||||
|
|
||||||
private def copy(
|
|
||||||
limit: Int = limit,
|
|
||||||
dynamicAging: Boolean = dynamicAging,
|
|
||||||
idleSettings: Option[IdleSettings] = idleSettings): LeastFrequentlyUsedSettings =
|
|
||||||
new LeastFrequentlyUsedSettings(limit, dynamicAging, idleSettings)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private[akka] def oldDefault(idleTimeout: FiniteDuration): PassivationStrategySettings =
|
private[akka] def oldDefault(idleTimeout: FiniteDuration): PassivationStrategySettings =
|
||||||
|
|
@ -743,14 +693,15 @@ final class ClusterShardingSettings(
|
||||||
rememberEntitiesStoreMode: ClusterShardingSettings.RememberEntitiesStoreMode): ClusterShardingSettings =
|
rememberEntitiesStoreMode: ClusterShardingSettings.RememberEntitiesStoreMode): ClusterShardingSettings =
|
||||||
copy(rememberEntitiesStoreMode = rememberEntitiesStoreMode)
|
copy(rememberEntitiesStoreMode = rememberEntitiesStoreMode)
|
||||||
|
|
||||||
@deprecated("See passivationStrategySettings.idleTimeout instead", since = "2.6.18")
|
@deprecated("See passivationStrategySettings.idleEntitySettings instead", since = "2.6.18")
|
||||||
def passivateIdleEntityAfter: FiniteDuration = passivationStrategySettings.idleSettings.timeout
|
def passivateIdleEntityAfter: FiniteDuration =
|
||||||
|
passivationStrategySettings.idleEntitySettings.fold(Duration.Zero)(_.timeout)
|
||||||
|
|
||||||
@deprecated("Use withIdlePassivationStrategy instead", since = "2.6.18")
|
@deprecated("Use withPassivationStrategy instead", since = "2.6.18")
|
||||||
def withPassivateIdleEntityAfter(duration: FiniteDuration): ClusterShardingSettings =
|
def withPassivateIdleEntityAfter(duration: FiniteDuration): ClusterShardingSettings =
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration))
|
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration))
|
||||||
|
|
||||||
@deprecated("Use withIdlePassivationStrategy instead", since = "2.6.18")
|
@deprecated("Use withPassivationStrategy instead", since = "2.6.18")
|
||||||
def withPassivateIdleEntityAfter(duration: java.time.Duration): ClusterShardingSettings =
|
def withPassivateIdleEntityAfter(duration: java.time.Duration): ClusterShardingSettings =
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration.asScala))
|
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration.asScala))
|
||||||
|
|
||||||
|
|
@ -760,24 +711,6 @@ final class ClusterShardingSettings(
|
||||||
def withNoPassivationStrategy(): ClusterShardingSettings =
|
def withNoPassivationStrategy(): ClusterShardingSettings =
|
||||||
copy(passivationStrategySettings = ClusterShardingSettings.PassivationStrategySettings.disabled)
|
copy(passivationStrategySettings = ClusterShardingSettings.PassivationStrategySettings.disabled)
|
||||||
|
|
||||||
def withIdlePassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.IdleSettings): ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withIdleStrategy(settings))
|
|
||||||
|
|
||||||
def withLeastRecentlyUsedPassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.LeastRecentlyUsedSettings)
|
|
||||||
: ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withLeastRecentlyUsedStrategy(settings))
|
|
||||||
|
|
||||||
def withMostRecentlyUsedPassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.MostRecentlyUsedSettings): ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withMostRecentlyUsedStrategy(settings))
|
|
||||||
|
|
||||||
def withLeastFrequentlyUsedPassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.LeastFrequentlyUsedSettings)
|
|
||||||
: ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withLeastFrequentlyUsedStrategy(settings))
|
|
||||||
|
|
||||||
def withShardRegionQueryTimeout(duration: FiniteDuration): ClusterShardingSettings =
|
def withShardRegionQueryTimeout(duration: FiniteDuration): ClusterShardingSettings =
|
||||||
copy(shardRegionQueryTimeout = duration)
|
copy(shardRegionQueryTimeout = duration)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ akka.cluster.sharding {
|
||||||
# Default is ddata for backwards compatibility.
|
# Default is ddata for backwards compatibility.
|
||||||
remember-entities-store = "ddata"
|
remember-entities-store = "ddata"
|
||||||
|
|
||||||
# Deprecated: use the `passivation.idle.timeout` for 'idle' `passivation.strategy` instead.
|
# Deprecated: use the `passivation.default-idle-strategy.idle-entity.timeout` setting instead.
|
||||||
# Set this to a time duration to have sharding passivate entities when they have not
|
# Set this to a time duration to have sharding passivate entities when they have not
|
||||||
# received any message in this length of time. Set to 'off' to disable.
|
# received any message in this length of time. Set to 'off' to disable.
|
||||||
# It is always disabled if `remember-entities` is enabled.
|
# It is always disabled if `remember-entities` is enabled.
|
||||||
|
|
@ -36,87 +36,84 @@ akka.cluster.sharding {
|
||||||
|
|
||||||
# Automatic entity passivation settings.
|
# Automatic entity passivation settings.
|
||||||
passivation {
|
passivation {
|
||||||
# Passivation strategy to use. Possible values are:
|
|
||||||
# - "idle"
|
# Automatic passivation strategy to use.
|
||||||
# - "least-recently-used"
|
|
||||||
# - "most-recently-used"
|
|
||||||
# - "least-frequently-used"
|
|
||||||
# Set to "none" or "off" to disable automatic passivation.
|
# Set to "none" or "off" to disable automatic passivation.
|
||||||
|
# Set to "default-strategy" to switch to the recommended default strategy with an active entity limit.
|
||||||
|
# See the strategy-defaults section for possible passivation strategy settings and default values.
|
||||||
# Passivation strategies are always disabled if `remember-entities` is enabled.
|
# Passivation strategies are always disabled if `remember-entities` is enabled.
|
||||||
strategy = "idle"
|
strategy = "default-idle-strategy"
|
||||||
|
|
||||||
# Idle passivation strategy.
|
# Default passivation strategy without active entity limit; time out idle entities after 2 minutes.
|
||||||
# Passivate entities when they have not received a message for a specified length of time.
|
default-idle-strategy {
|
||||||
idle {
|
idle-entity.timeout = 120s
|
||||||
# Passivate idle entities after the timeout.
|
|
||||||
timeout = 120s
|
|
||||||
|
|
||||||
# Check idle entities every interval. Set to "default" to use half the timeout by default.
|
|
||||||
interval = default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Least recently used passivation strategy.
|
# Recommended default strategy for automatic passivation with an active entity limit.
|
||||||
# Passivate the least recently used entities when the number of active entities in a shard region
|
# Configured with a segmented least recently used (SLRU) replacement policy.
|
||||||
# reaches a limit. The per-region limit is divided evenly among the active shards in a region.
|
default-strategy {
|
||||||
least-recently-used {
|
# Default limit of 100k active entities in a shard region (in a cluster node).
|
||||||
# Limit of active entities in a shard region.
|
active-entity-limit = 100000
|
||||||
limit = 100000
|
|
||||||
|
|
||||||
# Optionally use a "segmented" least recently used strategy.
|
# Segmented LRU replacement policy with an 80% "protected" level by default.
|
||||||
# Disabled when segmented.levels are set to "none" or "off".
|
replacement {
|
||||||
segmented {
|
policy = least-recently-used
|
||||||
# Number of segmented levels.
|
least-recently-used {
|
||||||
levels = none
|
segmented {
|
||||||
|
levels = 2
|
||||||
# Fractional proportions for the segmented levels.
|
proportions = [0.2, 0.8]
|
||||||
# If empty then segments are divided evenly by the number of levels.
|
}
|
||||||
proportions = []
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Optionally passivate entities when they have not received a message for a specified length of time.
|
strategy-defaults {
|
||||||
idle {
|
# Passivate entities when they have not received a message for a specified length of time.
|
||||||
# Passivate idle entities after the timeout. Set to "off" to disable.
|
idle-entity {
|
||||||
timeout = off
|
# Passivate idle entities after the timeout. Set to "none" or "off" to disable.
|
||||||
|
timeout = none
|
||||||
|
|
||||||
# Check idle entities every interval. Set to "default" to use half the timeout by default.
|
# Check idle entities every interval. Set to "default" to use half the timeout by default.
|
||||||
interval = default
|
interval = default
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# Most recently used passivation strategy.
|
|
||||||
# Passivate the most recently used entities when the number of active entities in a shard region
|
|
||||||
# reaches a limit. The per-region limit is divided evenly among the active shards in a region.
|
|
||||||
most-recently-used {
|
|
||||||
# Limit of active entities in a shard region.
|
# Limit of active entities in a shard region.
|
||||||
limit = 100000
|
# Passivate entities when the number of active entities in a shard region reaches this limit.
|
||||||
|
# The per-region limit is divided evenly among the active shards in a region.
|
||||||
|
# Set to "none" or "off" to disable limit-based automatic passivation, to only use idle entity timeouts.
|
||||||
|
active-entity-limit = none
|
||||||
|
|
||||||
# Optionally passivate entities when they have not received a message for a specified length of time.
|
# Entity replacement settings, for when the active entity limit is reached.
|
||||||
idle {
|
replacement {
|
||||||
# Passivate idle entities after the timeout. Set to "off" to disable.
|
# Entity replacement policy to use when the active entity limit is reached. Possible values are:
|
||||||
timeout = off
|
# - "least-recently-used"
|
||||||
|
# - "most-recently-used"
|
||||||
|
# - "least-frequently-used"
|
||||||
|
# Set to "none" or "off" to disable the replacement policy and ignore the active entity limit.
|
||||||
|
policy = none
|
||||||
|
|
||||||
# Check idle entities every interval. Set to "default" to use half the timeout by default.
|
# Least recently used entity replacement policy.
|
||||||
interval = default
|
least-recently-used {
|
||||||
}
|
# Optionally use a "segmented" least recently used strategy.
|
||||||
}
|
# Disabled when segmented.levels are set to "none" or "off".
|
||||||
|
segmented {
|
||||||
|
# Number of segmented levels.
|
||||||
|
levels = none
|
||||||
|
|
||||||
# Least frequently used passivation strategy.
|
# Fractional proportions for the segmented levels.
|
||||||
# Passivate the least frequently used entities when the number of active entities in a shard region
|
# If empty then segments are divided evenly by the number of levels.
|
||||||
# reaches a limit. The per-region limit is divided evenly among the active shards in a region.
|
proportions = []
|
||||||
least-frequently-used {
|
}
|
||||||
# Limit of active entities in a shard region.
|
}
|
||||||
limit = 100000
|
|
||||||
|
|
||||||
# New frequency counts will be "dynamically aged" when enabled.
|
# Most recently used entity replacement policy.
|
||||||
dynamic-aging = off
|
most-recently-used {}
|
||||||
|
|
||||||
# Optionally passivate entities when they have not received a message for a specified length of time.
|
# Least frequently used entity replacement policy.
|
||||||
idle {
|
least-frequently-used {
|
||||||
# Passivate idle entities after the timeout. Set to "off" to disable.
|
# New frequency counts will be "dynamically aged" when enabled.
|
||||||
timeout = off
|
dynamic-aging = off
|
||||||
|
}
|
||||||
# Check idle entities every interval. Set to "default" to use half the timeout by default.
|
|
||||||
interval = default
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,7 @@ object ClusterShardingSettings {
|
||||||
|
|
||||||
val coordinatorSingletonSettings = ClusterSingletonManagerSettings(config.getConfig("coordinator-singleton"))
|
val coordinatorSingletonSettings = ClusterSingletonManagerSettings(config.getConfig("coordinator-singleton"))
|
||||||
|
|
||||||
val passivationStrategySettings = PassivationStrategySettings(config)
|
val passivationStrategySettings = PassivationStrategySettings.fromSharding(config)
|
||||||
|
|
||||||
val lease = config.getString("use-lease") match {
|
val lease = config.getString("use-lease") match {
|
||||||
case s if s.isEmpty => None
|
case s if s.isEmpty => None
|
||||||
|
|
@ -130,71 +130,75 @@ object ClusterShardingSettings {
|
||||||
if (role == "") None else Option(role)
|
if (role == "") None else Option(role)
|
||||||
|
|
||||||
@ApiMayChange
|
@ApiMayChange
|
||||||
final class PassivationStrategySettings private (
|
final class PassivationStrategySettings private[akka] (
|
||||||
val strategy: String,
|
val idleEntitySettings: Option[PassivationStrategySettings.IdleSettings],
|
||||||
val idleSettings: PassivationStrategySettings.IdleSettings,
|
val activeEntityLimit: Option[Int],
|
||||||
val leastRecentlyUsedSettings: PassivationStrategySettings.LeastRecentlyUsedSettings,
|
val replacementPolicySettings: Option[PassivationStrategySettings.PolicySettings],
|
||||||
val mostRecentlyUsedSettings: PassivationStrategySettings.MostRecentlyUsedSettings,
|
|
||||||
val leastFrequentlyUsedSettings: PassivationStrategySettings.LeastFrequentlyUsedSettings,
|
|
||||||
private[akka] val oldSettingUsed: Boolean) {
|
private[akka] val oldSettingUsed: Boolean) {
|
||||||
|
|
||||||
def this(
|
def this(
|
||||||
strategy: String,
|
idleEntitySettings: Option[PassivationStrategySettings.IdleSettings],
|
||||||
idleSettings: PassivationStrategySettings.IdleSettings,
|
activeEntityLimit: Option[Int],
|
||||||
leastRecentlyUsedSettings: PassivationStrategySettings.LeastRecentlyUsedSettings,
|
replacementPolicySettings: Option[PassivationStrategySettings.PolicySettings]) =
|
||||||
mostRecentlyUsedSettings: PassivationStrategySettings.MostRecentlyUsedSettings,
|
this(idleEntitySettings, activeEntityLimit, replacementPolicySettings, oldSettingUsed = false)
|
||||||
leastFrequentlyUsedSettings: PassivationStrategySettings.LeastFrequentlyUsedSettings) =
|
|
||||||
this(
|
|
||||||
strategy,
|
|
||||||
idleSettings,
|
|
||||||
leastRecentlyUsedSettings,
|
|
||||||
mostRecentlyUsedSettings,
|
|
||||||
leastFrequentlyUsedSettings,
|
|
||||||
oldSettingUsed = false)
|
|
||||||
|
|
||||||
import PassivationStrategySettings._
|
import PassivationStrategySettings._
|
||||||
|
|
||||||
def withIdleStrategy(settings: IdleSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(settings: IdleSettings): PassivationStrategySettings =
|
||||||
copy(strategy = "idle", idleSettings = settings, oldSettingUsed = false)
|
copy(idleEntitySettings = Some(settings), oldSettingUsed = false)
|
||||||
|
|
||||||
def withLeastRecentlyUsedStrategy(settings: LeastRecentlyUsedSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(timeout: FiniteDuration): PassivationStrategySettings =
|
||||||
copy(strategy = "least-recently-used", leastRecentlyUsedSettings = settings)
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout))
|
||||||
|
|
||||||
def withMostRecentlyUsedStrategy(settings: MostRecentlyUsedSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(timeout: FiniteDuration, interval: FiniteDuration): PassivationStrategySettings =
|
||||||
copy(strategy = "most-recently-used", mostRecentlyUsedSettings = settings)
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout).withInterval(interval))
|
||||||
|
|
||||||
def withLeastFrequentlyUsedStrategy(settings: LeastFrequentlyUsedSettings): PassivationStrategySettings =
|
def withIdleEntityPassivation(timeout: java.time.Duration): PassivationStrategySettings =
|
||||||
copy(strategy = "least-frequently-used", leastFrequentlyUsedSettings = settings)
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout))
|
||||||
|
|
||||||
|
def withIdleEntityPassivation(
|
||||||
|
timeout: java.time.Duration,
|
||||||
|
interval: java.time.Duration): PassivationStrategySettings =
|
||||||
|
withIdleEntityPassivation(IdleSettings.defaults.withTimeout(timeout).withInterval(interval))
|
||||||
|
|
||||||
|
def withActiveEntityLimit(limit: Int): PassivationStrategySettings =
|
||||||
|
copy(activeEntityLimit = Some(limit))
|
||||||
|
|
||||||
|
def withReplacementPolicy(settings: PolicySettings): PassivationStrategySettings =
|
||||||
|
copy(replacementPolicySettings = Some(settings))
|
||||||
|
|
||||||
|
def withLeastRecentlyUsedReplacement(): PassivationStrategySettings =
|
||||||
|
withReplacementPolicy(LeastRecentlyUsedSettings.defaults)
|
||||||
|
|
||||||
|
def withMostRecentlyUsedReplacement(): PassivationStrategySettings =
|
||||||
|
withReplacementPolicy(MostRecentlyUsedSettings.defaults)
|
||||||
|
|
||||||
|
def withLeastFrequentlyUsedReplacement(): PassivationStrategySettings =
|
||||||
|
withReplacementPolicy(LeastFrequentlyUsedSettings.defaults)
|
||||||
|
|
||||||
private[akka] def withOldIdleStrategy(timeout: FiniteDuration): PassivationStrategySettings =
|
private[akka] def withOldIdleStrategy(timeout: FiniteDuration): PassivationStrategySettings =
|
||||||
copy(strategy = "idle", idleSettings = idleSettings.withTimeout(timeout), oldSettingUsed = true)
|
copy(
|
||||||
|
idleEntitySettings = Some(new IdleSettings(timeout, None)),
|
||||||
|
activeEntityLimit = None,
|
||||||
|
replacementPolicySettings = None,
|
||||||
|
oldSettingUsed = true)
|
||||||
|
|
||||||
private def copy(
|
private def copy(
|
||||||
strategy: String,
|
idleEntitySettings: Option[IdleSettings] = idleEntitySettings,
|
||||||
idleSettings: IdleSettings = idleSettings,
|
activeEntityLimit: Option[Int] = activeEntityLimit,
|
||||||
leastRecentlyUsedSettings: LeastRecentlyUsedSettings = leastRecentlyUsedSettings,
|
replacementPolicySettings: Option[PolicySettings] = replacementPolicySettings,
|
||||||
mostRecentlyUsedSettings: MostRecentlyUsedSettings = mostRecentlyUsedSettings,
|
|
||||||
leastFrequentlyUsedSettings: LeastFrequentlyUsedSettings = leastFrequentlyUsedSettings,
|
|
||||||
oldSettingUsed: Boolean = oldSettingUsed): PassivationStrategySettings =
|
oldSettingUsed: Boolean = oldSettingUsed): PassivationStrategySettings =
|
||||||
new PassivationStrategySettings(
|
new PassivationStrategySettings(idleEntitySettings, activeEntityLimit, replacementPolicySettings, oldSettingUsed)
|
||||||
strategy,
|
|
||||||
idleSettings,
|
|
||||||
leastRecentlyUsedSettings,
|
|
||||||
mostRecentlyUsedSettings,
|
|
||||||
leastFrequentlyUsedSettings,
|
|
||||||
oldSettingUsed)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object PassivationStrategySettings {
|
object PassivationStrategySettings {
|
||||||
val defaults = new PassivationStrategySettings(
|
val defaults = new PassivationStrategySettings(
|
||||||
strategy = "idle",
|
idleEntitySettings = None,
|
||||||
IdleSettings.defaults,
|
activeEntityLimit = None,
|
||||||
LeastRecentlyUsedSettings.defaults,
|
replacementPolicySettings = None,
|
||||||
MostRecentlyUsedSettings.defaults,
|
|
||||||
LeastFrequentlyUsedSettings.defaults,
|
|
||||||
oldSettingUsed = false)
|
oldSettingUsed = false)
|
||||||
|
|
||||||
val disabled: PassivationStrategySettings = defaults.copy(strategy = "none")
|
val disabled: PassivationStrategySettings = defaults
|
||||||
|
|
||||||
object IdleSettings {
|
object IdleSettings {
|
||||||
val defaults: IdleSettings = new IdleSettings(timeout = 2.minutes, interval = None)
|
val defaults: IdleSettings = new IdleSettings(timeout = 2.minutes, interval = None)
|
||||||
|
|
@ -207,9 +211,11 @@ object ClusterShardingSettings {
|
||||||
new IdleSettings(timeout, interval)
|
new IdleSettings(timeout, interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
def optional(config: Config): Option[IdleSettings] = {
|
def optional(config: Config): Option[IdleSettings] =
|
||||||
if (toRootLowerCase(config.getString("timeout")) == "off") None else Some(IdleSettings(config))
|
toRootLowerCase(config.getString("timeout")) match {
|
||||||
}
|
case "off" | "none" => None
|
||||||
|
case _ => Some(IdleSettings(config))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class IdleSettings(val timeout: FiniteDuration, val interval: Option[FiniteDuration]) {
|
final class IdleSettings(val timeout: FiniteDuration, val interval: Option[FiniteDuration]) {
|
||||||
|
|
@ -226,15 +232,29 @@ object ClusterShardingSettings {
|
||||||
new IdleSettings(timeout, interval)
|
new IdleSettings(timeout, interval)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object PolicySettings {
|
||||||
|
def apply(config: Config): PolicySettings =
|
||||||
|
toRootLowerCase(config.getString("policy")) match {
|
||||||
|
case "least-recently-used" => LeastRecentlyUsedSettings(config.getConfig("least-recently-used"))
|
||||||
|
case "most-recently-used" => MostRecentlyUsedSettings(config.getConfig("most-recently-used"))
|
||||||
|
case "least-frequently-used" => LeastFrequentlyUsedSettings(config.getConfig("least-frequently-used"))
|
||||||
|
}
|
||||||
|
|
||||||
|
def optional(config: Config): Option[PolicySettings] =
|
||||||
|
toRootLowerCase(config.getString("policy")) match {
|
||||||
|
case "off" | "none" => None
|
||||||
|
case _ => Some(PolicySettings(config))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sealed trait PolicySettings
|
||||||
|
|
||||||
object LeastRecentlyUsedSettings {
|
object LeastRecentlyUsedSettings {
|
||||||
val defaults: LeastRecentlyUsedSettings =
|
val defaults: LeastRecentlyUsedSettings = new LeastRecentlyUsedSettings(segmentedSettings = None)
|
||||||
new LeastRecentlyUsedSettings(limit = 100000, segmentedSettings = None, idleSettings = None)
|
|
||||||
|
|
||||||
def apply(config: Config): LeastRecentlyUsedSettings = {
|
def apply(config: Config): LeastRecentlyUsedSettings = {
|
||||||
val limit = config.getInt("limit")
|
|
||||||
val idleSettings = IdleSettings.optional(config.getConfig("idle"))
|
|
||||||
val segmentedSettings = SegmentedSettings.optional(config.getConfig("segmented"))
|
val segmentedSettings = SegmentedSettings.optional(config.getConfig("segmented"))
|
||||||
new LeastRecentlyUsedSettings(limit, segmentedSettings, idleSettings)
|
new LeastRecentlyUsedSettings(segmentedSettings)
|
||||||
}
|
}
|
||||||
|
|
||||||
object SegmentedSettings {
|
object SegmentedSettings {
|
||||||
|
|
@ -266,133 +286,78 @@ object ClusterShardingSettings {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class LeastRecentlyUsedSettings(
|
final class LeastRecentlyUsedSettings(val segmentedSettings: Option[LeastRecentlyUsedSettings.SegmentedSettings])
|
||||||
val limit: Int,
|
extends PolicySettings {
|
||||||
val segmentedSettings: Option[LeastRecentlyUsedSettings.SegmentedSettings],
|
import LeastRecentlyUsedSettings.SegmentedSettings
|
||||||
val idleSettings: Option[IdleSettings]) {
|
|
||||||
|
|
||||||
def withLimit(limit: Int): LeastRecentlyUsedSettings = copy(limit = limit)
|
def withSegmented(levels: Int): LeastRecentlyUsedSettings =
|
||||||
|
copy(segmentedSettings = Some(new SegmentedSettings(levels, Nil)))
|
||||||
|
|
||||||
def withSegmented(levels: Int): LeastRecentlyUsedSettings = withSegmented(levels, Nil)
|
def withSegmented(proportions: immutable.Seq[Double]): LeastRecentlyUsedSettings =
|
||||||
|
copy(segmentedSettings = Some(new SegmentedSettings(proportions.size, proportions)))
|
||||||
|
|
||||||
def withSegmented(levels: Int, proportions: immutable.Seq[Double]): LeastRecentlyUsedSettings =
|
def withSegmentedProportions(proportions: java.util.List[java.lang.Double]): LeastRecentlyUsedSettings =
|
||||||
copy(segmentedSettings = Some(new LeastRecentlyUsedSettings.SegmentedSettings(levels, proportions)))
|
withSegmented(immutableSeq(proportions).map(_.toDouble))
|
||||||
|
|
||||||
def withSegmentedProportions(
|
private def copy(segmentedSettings: Option[SegmentedSettings]): LeastRecentlyUsedSettings =
|
||||||
levels: Int,
|
new LeastRecentlyUsedSettings(segmentedSettings)
|
||||||
proportions: java.util.List[java.lang.Double]): LeastRecentlyUsedSettings =
|
|
||||||
withSegmented(levels, immutableSeq(proportions).map(_.toDouble))
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration): LeastRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, None)))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration): LeastRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration, interval: FiniteDuration): LeastRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, Some(interval))))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration, interval: java.time.Duration): LeastRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala, interval.asScala)
|
|
||||||
|
|
||||||
private def copy(
|
|
||||||
limit: Int = limit,
|
|
||||||
segmentedSettings: Option[LeastRecentlyUsedSettings.SegmentedSettings] = segmentedSettings,
|
|
||||||
idleSettings: Option[IdleSettings] = idleSettings): LeastRecentlyUsedSettings =
|
|
||||||
new LeastRecentlyUsedSettings(limit, segmentedSettings, idleSettings)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object MostRecentlyUsedSettings {
|
object MostRecentlyUsedSettings {
|
||||||
val defaults: MostRecentlyUsedSettings = new MostRecentlyUsedSettings(limit = 100000, idleSettings = None)
|
val defaults: MostRecentlyUsedSettings = new MostRecentlyUsedSettings
|
||||||
|
|
||||||
def apply(config: Config): MostRecentlyUsedSettings = {
|
def apply(config: Config): MostRecentlyUsedSettings = {
|
||||||
val limit = config.getInt("limit")
|
val _ = config // not used
|
||||||
val idleSettings = IdleSettings.optional(config.getConfig("idle"))
|
new MostRecentlyUsedSettings
|
||||||
new MostRecentlyUsedSettings(limit, idleSettings)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class MostRecentlyUsedSettings(val limit: Int, val idleSettings: Option[IdleSettings]) {
|
final class MostRecentlyUsedSettings extends PolicySettings
|
||||||
|
|
||||||
def withLimit(limit: Int): MostRecentlyUsedSettings = copy(limit = limit)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration): MostRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, None)))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration): MostRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration, interval: FiniteDuration): MostRecentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, Some(interval))))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration, interval: java.time.Duration): MostRecentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala, interval.asScala)
|
|
||||||
|
|
||||||
private def copy(
|
|
||||||
limit: Int = limit,
|
|
||||||
idleSettings: Option[IdleSettings] = idleSettings): MostRecentlyUsedSettings =
|
|
||||||
new MostRecentlyUsedSettings(limit, idleSettings)
|
|
||||||
}
|
|
||||||
|
|
||||||
object LeastFrequentlyUsedSettings {
|
object LeastFrequentlyUsedSettings {
|
||||||
val defaults: LeastFrequentlyUsedSettings =
|
val defaults: LeastFrequentlyUsedSettings = new LeastFrequentlyUsedSettings(dynamicAging = false)
|
||||||
new LeastFrequentlyUsedSettings(limit = 100000, dynamicAging = false, idleSettings = None)
|
|
||||||
|
|
||||||
def apply(config: Config): LeastFrequentlyUsedSettings = {
|
def apply(config: Config): LeastFrequentlyUsedSettings = {
|
||||||
val limit = config.getInt("limit")
|
|
||||||
val dynamicAging = config.getBoolean("dynamic-aging")
|
val dynamicAging = config.getBoolean("dynamic-aging")
|
||||||
val idleSettings = IdleSettings.optional(config.getConfig("idle"))
|
new LeastFrequentlyUsedSettings(dynamicAging)
|
||||||
new LeastFrequentlyUsedSettings(limit, dynamicAging, idleSettings)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class LeastFrequentlyUsedSettings(
|
final class LeastFrequentlyUsedSettings(val dynamicAging: Boolean) extends PolicySettings {
|
||||||
val limit: Int,
|
|
||||||
val dynamicAging: Boolean,
|
|
||||||
val idleSettings: Option[IdleSettings]) {
|
|
||||||
|
|
||||||
def withLimit(limit: Int): LeastFrequentlyUsedSettings = copy(limit = limit)
|
|
||||||
|
|
||||||
def withDynamicAging(): LeastFrequentlyUsedSettings = withDynamicAging(enabled = true)
|
def withDynamicAging(): LeastFrequentlyUsedSettings = withDynamicAging(enabled = true)
|
||||||
|
|
||||||
def withDynamicAging(enabled: Boolean): LeastFrequentlyUsedSettings = copy(dynamicAging = enabled)
|
def withDynamicAging(enabled: Boolean): LeastFrequentlyUsedSettings = copy(dynamicAging = enabled)
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration): LeastFrequentlyUsedSettings =
|
private def copy(dynamicAging: Boolean): LeastFrequentlyUsedSettings =
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, None)))
|
new LeastFrequentlyUsedSettings(dynamicAging)
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration): LeastFrequentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala)
|
|
||||||
|
|
||||||
def withIdle(timeout: FiniteDuration, interval: FiniteDuration): LeastFrequentlyUsedSettings =
|
|
||||||
copy(idleSettings = Some(new IdleSettings(timeout, Some(interval))))
|
|
||||||
|
|
||||||
def withIdle(timeout: java.time.Duration, interval: java.time.Duration): LeastFrequentlyUsedSettings =
|
|
||||||
withIdle(timeout.asScala, interval.asScala)
|
|
||||||
|
|
||||||
private def copy(
|
|
||||||
limit: Int = limit,
|
|
||||||
dynamicAging: Boolean = dynamicAging,
|
|
||||||
idleSettings: Option[IdleSettings] = idleSettings): LeastFrequentlyUsedSettings =
|
|
||||||
new LeastFrequentlyUsedSettings(limit, dynamicAging, idleSettings)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def apply(config: Config): PassivationStrategySettings = {
|
def apply(config: Config): PassivationStrategySettings = {
|
||||||
val settings =
|
toRootLowerCase(config.getString("strategy")) match {
|
||||||
new PassivationStrategySettings(
|
case "off" | "none" => PassivationStrategySettings.disabled
|
||||||
strategy = toRootLowerCase(config.getString("passivation.strategy")),
|
case strategyName =>
|
||||||
idleSettings = IdleSettings(config.getConfig("passivation.idle")),
|
val strategyDefaults = config.getConfig("strategy-defaults")
|
||||||
leastRecentlyUsedSettings = LeastRecentlyUsedSettings(config.getConfig("passivation.least-recently-used")),
|
val strategyConfig = config.getConfig(strategyName).withFallback(strategyDefaults)
|
||||||
mostRecentlyUsedSettings = MostRecentlyUsedSettings(config.getConfig("passivation.most-recently-used")),
|
val idleEntitySettings = IdleSettings.optional(strategyConfig.getConfig("idle-entity"))
|
||||||
leastFrequentlyUsedSettings = LeastFrequentlyUsedSettings(
|
val activeEntityLimit = strategyConfig.getString("active-entity-limit") match {
|
||||||
config.getConfig("passivation.least-frequently-used")))
|
case "off" | "none" => None
|
||||||
|
case _ => Some(strategyConfig.getInt("active-entity-limit"))
|
||||||
|
}
|
||||||
|
val replacementPolicySettings = PolicySettings.optional(strategyConfig.getConfig("replacement"))
|
||||||
|
new PassivationStrategySettings(idleEntitySettings, activeEntityLimit, replacementPolicySettings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def fromSharding(shardingConfig: Config): PassivationStrategySettings = {
|
||||||
// default to old setting if it exists (defined in application.conf), overriding the new settings
|
// default to old setting if it exists (defined in application.conf), overriding the new settings
|
||||||
if (config.hasPath("passivate-idle-entity-after")) {
|
if (shardingConfig.hasPath("passivate-idle-entity-after")) {
|
||||||
val timeout =
|
val timeout =
|
||||||
if (toRootLowerCase(config.getString("passivate-idle-entity-after")) == "off") Duration.Zero
|
if (toRootLowerCase(shardingConfig.getString("passivate-idle-entity-after")) == "off") Duration.Zero
|
||||||
else config.getDuration("passivate-idle-entity-after", MILLISECONDS).millis
|
else shardingConfig.getDuration("passivate-idle-entity-after", MILLISECONDS).millis
|
||||||
settings.withOldIdleStrategy(timeout)
|
oldDefault(timeout)
|
||||||
} else {
|
} else {
|
||||||
settings
|
PassivationStrategySettings(shardingConfig.getConfig("passivation"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,9 +382,10 @@ object ClusterShardingSettings {
|
||||||
extends PassivationStrategy
|
extends PassivationStrategy
|
||||||
|
|
||||||
private[akka] object LeastRecentlyUsedPassivationStrategy {
|
private[akka] object LeastRecentlyUsedPassivationStrategy {
|
||||||
def apply(settings: PassivationStrategySettings.LeastRecentlyUsedSettings): LeastRecentlyUsedPassivationStrategy = {
|
def apply(
|
||||||
val limit = settings.limit
|
settings: PassivationStrategySettings.LeastRecentlyUsedSettings,
|
||||||
val idle = settings.idleSettings.map(IdlePassivationStrategy.apply)
|
limit: Int,
|
||||||
|
idle: Option[IdlePassivationStrategy]): LeastRecentlyUsedPassivationStrategy = {
|
||||||
settings.segmentedSettings match {
|
settings.segmentedSettings match {
|
||||||
case Some(segmented) =>
|
case Some(segmented) =>
|
||||||
val proportions =
|
val proportions =
|
||||||
|
|
@ -438,21 +404,15 @@ object ClusterShardingSettings {
|
||||||
idle: Option[IdlePassivationStrategy])
|
idle: Option[IdlePassivationStrategy])
|
||||||
extends PassivationStrategy
|
extends PassivationStrategy
|
||||||
|
|
||||||
private[akka] object MostRecentlyUsedPassivationStrategy {
|
|
||||||
def apply(settings: PassivationStrategySettings.MostRecentlyUsedSettings): MostRecentlyUsedPassivationStrategy =
|
|
||||||
MostRecentlyUsedPassivationStrategy(settings.limit, settings.idleSettings.map(IdlePassivationStrategy.apply))
|
|
||||||
}
|
|
||||||
|
|
||||||
private[akka] case class MostRecentlyUsedPassivationStrategy(limit: Int, idle: Option[IdlePassivationStrategy])
|
private[akka] case class MostRecentlyUsedPassivationStrategy(limit: Int, idle: Option[IdlePassivationStrategy])
|
||||||
extends PassivationStrategy
|
extends PassivationStrategy
|
||||||
|
|
||||||
private[akka] object LeastFrequentlyUsedPassivationStrategy {
|
private[akka] object LeastFrequentlyUsedPassivationStrategy {
|
||||||
def apply(
|
def apply(
|
||||||
settings: PassivationStrategySettings.LeastFrequentlyUsedSettings): LeastFrequentlyUsedPassivationStrategy =
|
settings: PassivationStrategySettings.LeastFrequentlyUsedSettings,
|
||||||
LeastFrequentlyUsedPassivationStrategy(
|
limit: Int,
|
||||||
settings.limit,
|
idle: Option[IdlePassivationStrategy]): LeastFrequentlyUsedPassivationStrategy =
|
||||||
settings.dynamicAging,
|
LeastFrequentlyUsedPassivationStrategy(limit, settings.dynamicAging, idle)
|
||||||
settings.idleSettings.map(IdlePassivationStrategy.apply))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private[akka] case class LeastFrequentlyUsedPassivationStrategy(
|
private[akka] case class LeastFrequentlyUsedPassivationStrategy(
|
||||||
|
|
@ -467,22 +427,28 @@ object ClusterShardingSettings {
|
||||||
*/
|
*/
|
||||||
@InternalApi
|
@InternalApi
|
||||||
private[akka] object PassivationStrategy {
|
private[akka] object PassivationStrategy {
|
||||||
def apply(settings: ClusterShardingSettings): PassivationStrategy = {
|
def apply(settings: ClusterShardingSettings): PassivationStrategy =
|
||||||
if (settings.rememberEntities) {
|
if (settings.rememberEntities) {
|
||||||
NoPassivationStrategy
|
NoPassivationStrategy
|
||||||
} else
|
} else {
|
||||||
settings.passivationStrategySettings.strategy match {
|
val idle = settings.passivationStrategySettings.idleEntitySettings match {
|
||||||
case "idle" if settings.passivationStrategySettings.idleSettings.timeout > Duration.Zero =>
|
case Some(idleSettings) if idleSettings.timeout > Duration.Zero => Some(IdlePassivationStrategy(idleSettings))
|
||||||
IdlePassivationStrategy(settings.passivationStrategySettings.idleSettings)
|
case _ => None
|
||||||
case "least-recently-used" =>
|
|
||||||
LeastRecentlyUsedPassivationStrategy(settings.passivationStrategySettings.leastRecentlyUsedSettings)
|
|
||||||
case "most-recently-used" =>
|
|
||||||
MostRecentlyUsedPassivationStrategy(settings.passivationStrategySettings.mostRecentlyUsedSettings)
|
|
||||||
case "least-frequently-used" =>
|
|
||||||
LeastFrequentlyUsedPassivationStrategy(settings.passivationStrategySettings.leastFrequentlyUsedSettings)
|
|
||||||
case _ => NoPassivationStrategy
|
|
||||||
}
|
}
|
||||||
}
|
settings.passivationStrategySettings.activeEntityLimit match {
|
||||||
|
case Some(limit) =>
|
||||||
|
settings.passivationStrategySettings.replacementPolicySettings match {
|
||||||
|
case Some(settings: PassivationStrategySettings.LeastRecentlyUsedSettings) =>
|
||||||
|
LeastRecentlyUsedPassivationStrategy(settings, limit, idle)
|
||||||
|
case Some(_: PassivationStrategySettings.MostRecentlyUsedSettings) =>
|
||||||
|
MostRecentlyUsedPassivationStrategy(limit, idle)
|
||||||
|
case Some(settings: PassivationStrategySettings.LeastFrequentlyUsedSettings) =>
|
||||||
|
LeastFrequentlyUsedPassivationStrategy(settings, limit, idle)
|
||||||
|
case _ => idle.getOrElse(NoPassivationStrategy)
|
||||||
|
}
|
||||||
|
case _ => idle.getOrElse(NoPassivationStrategy)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TuningParameters(
|
class TuningParameters(
|
||||||
|
|
@ -872,14 +838,15 @@ final class ClusterShardingSettings(
|
||||||
def withStateStoreMode(stateStoreMode: String): ClusterShardingSettings =
|
def withStateStoreMode(stateStoreMode: String): ClusterShardingSettings =
|
||||||
copy(stateStoreMode = stateStoreMode)
|
copy(stateStoreMode = stateStoreMode)
|
||||||
|
|
||||||
@deprecated("See passivationStrategySettings.idleTimeout instead", since = "2.6.18")
|
@deprecated("See passivationStrategySettings.idleEntitySettings instead", since = "2.6.18")
|
||||||
def passivateIdleEntityAfter: FiniteDuration = passivationStrategySettings.idleSettings.timeout
|
def passivateIdleEntityAfter: FiniteDuration =
|
||||||
|
passivationStrategySettings.idleEntitySettings.fold(Duration.Zero)(_.timeout)
|
||||||
|
|
||||||
@deprecated("Use withIdlePassivationStrategy instead", since = "2.6.18")
|
@deprecated("Use withPassivationStrategy instead", since = "2.6.18")
|
||||||
def withPassivateIdleAfter(duration: FiniteDuration): ClusterShardingSettings =
|
def withPassivateIdleAfter(duration: FiniteDuration): ClusterShardingSettings =
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration))
|
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration))
|
||||||
|
|
||||||
@deprecated("Use withIdlePassivationStrategy instead", since = "2.6.18")
|
@deprecated("Use withPassivationStrategy instead", since = "2.6.18")
|
||||||
def withPassivateIdleAfter(duration: java.time.Duration): ClusterShardingSettings =
|
def withPassivateIdleAfter(duration: java.time.Duration): ClusterShardingSettings =
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration.asScala))
|
copy(passivationStrategySettings = passivationStrategySettings.withOldIdleStrategy(duration.asScala))
|
||||||
|
|
||||||
|
|
@ -889,24 +856,6 @@ final class ClusterShardingSettings(
|
||||||
def withNoPassivationStrategy(): ClusterShardingSettings =
|
def withNoPassivationStrategy(): ClusterShardingSettings =
|
||||||
copy(passivationStrategySettings = ClusterShardingSettings.PassivationStrategySettings.disabled)
|
copy(passivationStrategySettings = ClusterShardingSettings.PassivationStrategySettings.disabled)
|
||||||
|
|
||||||
def withIdlePassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.IdleSettings): ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withIdleStrategy(settings))
|
|
||||||
|
|
||||||
def withLeastRecentlyUsedPassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.LeastRecentlyUsedSettings)
|
|
||||||
: ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withLeastRecentlyUsedStrategy(settings))
|
|
||||||
|
|
||||||
def withMostRecentlyUsedPassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.MostRecentlyUsedSettings): ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withMostRecentlyUsedStrategy(settings))
|
|
||||||
|
|
||||||
def withLeastFrequentlyUsedPassivationStrategy(
|
|
||||||
settings: ClusterShardingSettings.PassivationStrategySettings.LeastFrequentlyUsedSettings)
|
|
||||||
: ClusterShardingSettings =
|
|
||||||
copy(passivationStrategySettings = passivationStrategySettings.withLeastFrequentlyUsedStrategy(settings))
|
|
||||||
|
|
||||||
def withShardRegionQueryTimeout(duration: FiniteDuration): ClusterShardingSettings =
|
def withShardRegionQueryTimeout(duration: FiniteDuration): ClusterShardingSettings =
|
||||||
copy(shardRegionQueryTimeout = duration)
|
copy(shardRegionQueryTimeout = duration)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -674,7 +674,8 @@ private[akka] class ShardRegion(
|
||||||
if (settings.passivationStrategySettings.oldSettingUsed) {
|
if (settings.passivationStrategySettings.oldSettingUsed) {
|
||||||
log.warning(
|
log.warning(
|
||||||
"The `akka.cluster.sharding.passivate-idle-entity-after` setting and associated methods are deprecated. " +
|
"The `akka.cluster.sharding.passivate-idle-entity-after` setting and associated methods are deprecated. " +
|
||||||
"See automatic passivation strategies and use the `akka.cluster.sharding.passivation.idle.timeout` setting.")
|
"Use the `akka.cluster.sharding.passivation.default-idle-strategy.idle-entity.timeout` setting instead. " +
|
||||||
|
"See the documentation and reference config for more information on automatic passivation strategies.")
|
||||||
}
|
}
|
||||||
if (settings.rememberEntities) {
|
if (settings.rememberEntities) {
|
||||||
log.debug("{}: Entities will not be passivated automatically because 'rememberEntities' is enabled.", typeName)
|
log.debug("{}: Entities will not be passivated automatically because 'rememberEntities' is enabled.", typeName)
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,8 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
"allow timeout for (default) idle passivation strategy to be configured (via config)" in {
|
"allow timeout for (default) idle passivation strategy to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-idle-timeout
|
#passivation-idle-timeout
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
default-idle-strategy.idle-entity.timeout = 3 minutes
|
||||||
idle.timeout = 3 minutes
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#passivation-idle-timeout
|
#passivation-idle-timeout
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
||||||
|
|
@ -48,8 +46,8 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow timeout for (default) idle passivation strategy to be configured (via factory method)" in {
|
"allow timeout for (default) idle passivation strategy to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withIdlePassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.IdleSettings.defaults.withTimeout(42.seconds))
|
ClusterShardingSettings.PassivationStrategySettings.defaults.withIdleEntityPassivation(timeout = 42.seconds))
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
||||||
timeout = 42.seconds,
|
timeout = 42.seconds,
|
||||||
interval = 21.seconds)
|
interval = 21.seconds)
|
||||||
|
|
@ -57,9 +55,9 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow timeout and interval for (default) idle passivation strategy to be configured (via config)" in {
|
"allow timeout and interval for (default) idle passivation strategy to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
default-idle-strategy {
|
||||||
idle {
|
idle-entity {
|
||||||
timeout = 3 minutes
|
timeout = 3 minutes
|
||||||
interval = 1 minute
|
interval = 1 minute
|
||||||
}
|
}
|
||||||
|
|
@ -72,25 +70,71 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow timeout and interval for (default) idle passivation strategy to be configured (via factory method)" in {
|
"allow timeout and interval for (default) idle passivation strategy to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withIdlePassivationStrategy(
|
.withPassivationStrategy(ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
ClusterShardingSettings.PassivationStrategySettings.IdleSettings.defaults
|
.withIdleEntityPassivation(timeout = 42.seconds, interval = 42.millis))
|
||||||
.withTimeout(42.seconds)
|
|
||||||
.withInterval(42.millis))
|
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
||||||
timeout = 42.seconds,
|
timeout = 42.seconds,
|
||||||
interval = 42.millis)
|
interval = 42.millis)
|
||||||
}
|
}
|
||||||
|
|
||||||
"allow least recently used passivation strategy to be configured (via config)" in {
|
"allow new default passivation strategy to be enabled (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-least-recently-used
|
#passivation-new-default-strategy
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
strategy = default-strategy
|
||||||
strategy = least-recently-used
|
}
|
||||||
least-recently-used.limit = 1000000
|
#passivation-new-default-strategy
|
||||||
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
|
limit = 100000,
|
||||||
|
segmented = List(0.2, 0.8),
|
||||||
|
idle = None)
|
||||||
|
}
|
||||||
|
|
||||||
|
"allow new default passivation strategy limit to be configured (via config)" in {
|
||||||
|
settings("""
|
||||||
|
#passivation-new-default-strategy-configured
|
||||||
|
akka.cluster.sharding.passivation {
|
||||||
|
strategy = default-strategy
|
||||||
|
default-strategy {
|
||||||
|
active-entity-limit = 1000000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-least-recently-used
|
#passivation-new-default-strategy-configured
|
||||||
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
|
limit = 1000000,
|
||||||
|
segmented = List(0.2, 0.8),
|
||||||
|
idle = None)
|
||||||
|
}
|
||||||
|
|
||||||
|
"allow new default passivation strategy with idle timeout to be configured (via config)" in {
|
||||||
|
settings("""
|
||||||
|
#passivation-new-default-strategy-with-idle
|
||||||
|
akka.cluster.sharding.passivation {
|
||||||
|
strategy = default-strategy
|
||||||
|
default-strategy {
|
||||||
|
idle-entity.timeout = 30.minutes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#passivation-new-default-strategy-with-idle
|
||||||
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
|
limit = 100000,
|
||||||
|
segmented = List(0.2, 0.8),
|
||||||
|
idle = Some(ClusterShardingSettings.IdlePassivationStrategy(timeout = 30.minutes, interval = 15.minutes)))
|
||||||
|
}
|
||||||
|
|
||||||
|
"allow least recently used passivation strategy to be configured (via config)" in {
|
||||||
|
settings("""
|
||||||
|
#custom-passivation-strategy
|
||||||
|
#lru-policy
|
||||||
|
akka.cluster.sharding.passivation {
|
||||||
|
strategy = custom-lru-strategy
|
||||||
|
custom-lru-strategy {
|
||||||
|
active-entity-limit = 1000000
|
||||||
|
replacement.policy = least-recently-used
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#lru-policy
|
||||||
|
#custom-passivation-strategy
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
segmented = Nil,
|
segmented = Nil,
|
||||||
|
|
@ -99,8 +143,10 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least recently used passivation strategy to be configured (via factory method)" in {
|
"allow least recently used passivation strategy to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withLeastRecentlyUsedPassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.LeastRecentlyUsedSettings.defaults.withLimit(42000))
|
ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
|
.withActiveEntityLimit(42000)
|
||||||
|
.withLeastRecentlyUsedReplacement())
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
segmented = Nil,
|
segmented = Nil,
|
||||||
|
|
@ -109,20 +155,23 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow segmented least recently used passivation strategy to be configured (via config)" in {
|
"allow segmented least recently used passivation strategy to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-segmented-least-recently-used
|
#slru-policy
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
strategy = custom-slru-strategy
|
||||||
strategy = least-recently-used
|
custom-slru-strategy {
|
||||||
least-recently-used {
|
active-entity-limit = 1000000
|
||||||
limit = 1000000
|
replacement {
|
||||||
segmented {
|
policy = least-recently-used
|
||||||
levels = 2
|
least-recently-used {
|
||||||
proportions = [0.2, 0.8]
|
segmented {
|
||||||
|
levels = 2
|
||||||
|
proportions = [0.2, 0.8]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-segmented-least-recently-used
|
#slru-policy
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
segmented = List(0.2, 0.8),
|
segmented = List(0.2, 0.8),
|
||||||
|
|
@ -131,17 +180,20 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow 4-level segmented least recently used passivation strategy to be configured (via config)" in {
|
"allow 4-level segmented least recently used passivation strategy to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-s4-least-recently-used
|
#s4lru-policy
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
strategy = custom-s4lru-strategy
|
||||||
strategy = least-recently-used
|
custom-s4lru-strategy {
|
||||||
least-recently-used {
|
active-entity-limit = 1000000
|
||||||
limit = 1000000
|
replacement {
|
||||||
segmented.levels = 4
|
policy = least-recently-used
|
||||||
|
least-recently-used {
|
||||||
|
segmented.levels = 4
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-s4-least-recently-used
|
#s4lru-policy
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
segmented = List(0.25, 0.25, 0.25, 0.25),
|
segmented = List(0.25, 0.25, 0.25, 0.25),
|
||||||
|
|
@ -150,10 +202,10 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow segmented least recently used passivation strategy to be configured (via factory method)" in {
|
"allow segmented least recently used passivation strategy to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withLeastRecentlyUsedPassivationStrategy(
|
.withPassivationStrategy(ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
ClusterShardingSettings.PassivationStrategySettings.LeastRecentlyUsedSettings.defaults
|
.withActiveEntityLimit(42000)
|
||||||
.withLimit(42000)
|
.withReplacementPolicy(ClusterShardingSettings.PassivationStrategySettings.LeastRecentlyUsedSettings.defaults
|
||||||
.withSegmented(levels = 4, proportions = List(0.4, 0.3, 0.2, 0.1)))
|
.withSegmented(proportions = List(0.4, 0.3, 0.2, 0.1))))
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
segmented = List(0.4, 0.3, 0.2, 0.1),
|
segmented = List(0.4, 0.3, 0.2, 0.1),
|
||||||
|
|
@ -162,17 +214,14 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least recently used passivation strategy with idle timeout to be configured (via config)" in {
|
"allow least recently used passivation strategy with idle timeout to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-least-recently-used-with-idle
|
akka.cluster.sharding.passivation {
|
||||||
akka.cluster.sharding {
|
strategy = custom-lru-with-idle
|
||||||
passivation {
|
custom-lru-with-idle {
|
||||||
strategy = least-recently-used
|
active-entity-limit = 1000000
|
||||||
least-recently-used {
|
replacement.policy = least-recently-used
|
||||||
limit = 1000000
|
idle-entity.timeout = 30.minutes
|
||||||
idle.timeout = 30.minutes
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-least-recently-used-with-idle
|
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
segmented = Nil,
|
segmented = Nil,
|
||||||
|
|
@ -181,10 +230,11 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least recently used passivation strategy with idle timeout to be configured (via factory method)" in {
|
"allow least recently used passivation strategy with idle timeout to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withLeastRecentlyUsedPassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.LeastRecentlyUsedSettings.defaults
|
ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
.withLimit(42000)
|
.withActiveEntityLimit(42000)
|
||||||
.withIdle(timeout = 42.minutes))
|
.withLeastRecentlyUsedReplacement()
|
||||||
|
.withIdleEntityPassivation(timeout = 42.minutes))
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.LeastRecentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
segmented = Nil,
|
segmented = Nil,
|
||||||
|
|
@ -193,14 +243,15 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow most recently used passivation strategy to be configured (via config)" in {
|
"allow most recently used passivation strategy to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-most-recently-used
|
#mru-policy
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
strategy = custom-mru-strategy
|
||||||
strategy = most-recently-used
|
custom-mru-strategy {
|
||||||
most-recently-used.limit = 1000000
|
active-entity-limit = 1000000
|
||||||
|
replacement.policy = most-recently-used
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-most-recently-used
|
#mru-policy
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
idle = None)
|
idle = None)
|
||||||
|
|
@ -208,8 +259,10 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow most recently used passivation strategy to be configured (via factory method)" in {
|
"allow most recently used passivation strategy to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withMostRecentlyUsedPassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.MostRecentlyUsedSettings.defaults.withLimit(42000))
|
ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
|
.withActiveEntityLimit(42000)
|
||||||
|
.withMostRecentlyUsedReplacement())
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
idle = None)
|
idle = None)
|
||||||
|
|
@ -217,17 +270,14 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow most recently used passivation strategy with idle timeout to be configured (via config)" in {
|
"allow most recently used passivation strategy with idle timeout to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-most-recently-used-with-idle
|
akka.cluster.sharding.passivation {
|
||||||
akka.cluster.sharding {
|
strategy = custom-mru-with-idle
|
||||||
passivation {
|
custom-mru-with-idle {
|
||||||
strategy = most-recently-used
|
active-entity-limit = 1000000
|
||||||
most-recently-used {
|
replacement.policy = most-recently-used
|
||||||
limit = 1000000
|
idle-entity.timeout = 30.minutes
|
||||||
idle.timeout = 30.minutes
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-most-recently-used-with-idle
|
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
idle = Some(ClusterShardingSettings.IdlePassivationStrategy(timeout = 30.minutes, interval = 15.minutes)))
|
idle = Some(ClusterShardingSettings.IdlePassivationStrategy(timeout = 30.minutes, interval = 15.minutes)))
|
||||||
|
|
@ -235,10 +285,11 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow most recently used passivation strategy with idle timeout to be configured (via factory method)" in {
|
"allow most recently used passivation strategy with idle timeout to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withMostRecentlyUsedPassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.MostRecentlyUsedSettings.defaults
|
ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
.withLimit(42000)
|
.withActiveEntityLimit(42000)
|
||||||
.withIdle(timeout = 42.minutes))
|
.withMostRecentlyUsedReplacement()
|
||||||
|
.withIdleEntityPassivation(timeout = 42.minutes))
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.MostRecentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
idle = Some(ClusterShardingSettings.IdlePassivationStrategy(timeout = 42.minutes, interval = 21.minutes)))
|
idle = Some(ClusterShardingSettings.IdlePassivationStrategy(timeout = 42.minutes, interval = 21.minutes)))
|
||||||
|
|
@ -246,14 +297,15 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least frequently used passivation strategy to be configured (via config)" in {
|
"allow least frequently used passivation strategy to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-least-frequently-used
|
#lfu-policy
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
strategy = custom-lfu-strategy
|
||||||
strategy = least-frequently-used
|
custom-lfu-strategy {
|
||||||
least-frequently-used.limit = 1000000
|
active-entity-limit = 1000000
|
||||||
|
replacement.policy = least-frequently-used
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-least-frequently-used
|
#lfu-policy
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
dynamicAging = false,
|
dynamicAging = false,
|
||||||
|
|
@ -262,8 +314,10 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least frequently used passivation strategy to be configured (via factory method)" in {
|
"allow least frequently used passivation strategy to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withLeastFrequentlyUsedPassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.LeastFrequentlyUsedSettings.defaults.withLimit(42000))
|
ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
|
.withActiveEntityLimit(42000)
|
||||||
|
.withLeastFrequentlyUsedReplacement())
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
dynamicAging = false,
|
dynamicAging = false,
|
||||||
|
|
@ -272,17 +326,14 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least frequently used passivation strategy with idle timeout to be configured (via config)" in {
|
"allow least frequently used passivation strategy with idle timeout to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-least-frequently-used-with-idle
|
akka.cluster.sharding.passivation {
|
||||||
akka.cluster.sharding {
|
strategy = custom-lfu-with-idle
|
||||||
passivation {
|
custom-lfu-with-idle {
|
||||||
strategy = least-frequently-used
|
active-entity-limit = 1000000
|
||||||
least-frequently-used {
|
replacement.policy = least-frequently-used
|
||||||
limit = 1000000
|
idle-entity.timeout = 30.minutes
|
||||||
idle.timeout = 30.minutes
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-least-frequently-used-with-idle
|
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
||||||
limit = 1000000,
|
limit = 1000000,
|
||||||
dynamicAging = false,
|
dynamicAging = false,
|
||||||
|
|
@ -291,10 +342,11 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least frequently used passivation strategy with idle timeout to be configured (via factory method)" in {
|
"allow least frequently used passivation strategy with idle timeout to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withLeastFrequentlyUsedPassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.LeastFrequentlyUsedSettings.defaults
|
ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
.withLimit(42000)
|
.withActiveEntityLimit(42000)
|
||||||
.withIdle(timeout = 42.minutes))
|
.withLeastFrequentlyUsedReplacement()
|
||||||
|
.withIdleEntityPassivation(timeout = 42.minutes))
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
dynamicAging = false,
|
dynamicAging = false,
|
||||||
|
|
@ -303,17 +355,20 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least frequently used passivation strategy with dynamic aging to be configured (via config)" in {
|
"allow least frequently used passivation strategy with dynamic aging to be configured (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
#passivation-least-frequently-used-with-dynamic-aging
|
#lfuda-policy
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding.passivation {
|
||||||
passivation {
|
strategy = custom-lfu-with-dynamic-aging
|
||||||
strategy = least-frequently-used
|
custom-lfu-with-dynamic-aging {
|
||||||
least-frequently-used {
|
active-entity-limit = 1000
|
||||||
limit = 1000
|
replacement {
|
||||||
dynamic-aging = on
|
policy = least-frequently-used
|
||||||
|
least-frequently-used {
|
||||||
|
dynamic-aging = on
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#passivation-least-frequently-used-with-dynamic-aging
|
#lfuda-policy
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
||||||
limit = 1000,
|
limit = 1000,
|
||||||
dynamicAging = true,
|
dynamicAging = true,
|
||||||
|
|
@ -322,10 +377,12 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"allow least frequently used passivation strategy with dynamic aging to be configured (via factory method)" in {
|
"allow least frequently used passivation strategy with dynamic aging to be configured (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withLeastFrequentlyUsedPassivationStrategy(
|
.withPassivationStrategy(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.LeastFrequentlyUsedSettings.defaults
|
ClusterShardingSettings.PassivationStrategySettings.defaults
|
||||||
.withLimit(42000)
|
.withActiveEntityLimit(42000)
|
||||||
.withDynamicAging())
|
.withReplacementPolicy(
|
||||||
|
ClusterShardingSettings.PassivationStrategySettings.LeastFrequentlyUsedSettings.defaults
|
||||||
|
.withDynamicAging()))
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
.passivationStrategy shouldBe ClusterShardingSettings.LeastFrequentlyUsedPassivationStrategy(
|
||||||
limit = 42000,
|
limit = 42000,
|
||||||
dynamicAging = true,
|
dynamicAging = true,
|
||||||
|
|
@ -346,14 +403,14 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
"disable automatic passivation if idle timeout is set to zero (via config)" in {
|
"disable automatic passivation if idle timeout is set to zero (via config)" in {
|
||||||
settings("""
|
settings("""
|
||||||
akka.cluster.sharding.passivation.idle.timeout = 0
|
akka.cluster.sharding.passivation.default-idle-strategy.idle-entity.timeout = 0
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.NoPassivationStrategy
|
""").passivationStrategy shouldBe ClusterShardingSettings.NoPassivationStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
"disable automatic passivation if idle timeout is set to zero (via factory method)" in {
|
"disable automatic passivation if idle timeout is set to zero (via factory method)" in {
|
||||||
defaultSettings
|
defaultSettings
|
||||||
.withIdlePassivationStrategy(
|
.withPassivationStrategy(ClusterShardingSettings.PassivationStrategySettings.defaults.withIdleEntityPassivation(
|
||||||
ClusterShardingSettings.PassivationStrategySettings.IdleSettings.defaults.withTimeout(Duration.Zero))
|
timeout = Duration.Zero))
|
||||||
.passivationStrategy shouldBe ClusterShardingSettings.NoPassivationStrategy
|
.passivationStrategy shouldBe ClusterShardingSettings.NoPassivationStrategy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -367,7 +424,7 @@ class ClusterShardingSettingsSpec extends AnyWordSpec with Matchers {
|
||||||
settings("""
|
settings("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivate-idle-entity-after = 5 minutes
|
passivate-idle-entity-after = 5 minutes
|
||||||
passivation-strategy = least-recently-used
|
passivation.strategy = default-strategy
|
||||||
}
|
}
|
||||||
""").passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
""").passivationStrategy shouldBe ClusterShardingSettings.IdlePassivationStrategy(
|
||||||
timeout = 5.minutes,
|
timeout = 5.minutes,
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,6 @@ object EntityPassivationSpec {
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = none
|
strategy = none
|
||||||
idle.timeout = 1s
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""").withFallback(config)
|
""").withFallback(config)
|
||||||
|
|
@ -84,8 +83,9 @@ abstract class AbstractEntityPassivationSpec(config: Config, expectedEntities: I
|
||||||
import EntityPassivationSpec._
|
import EntityPassivationSpec._
|
||||||
|
|
||||||
val settings: ClusterShardingSettings = ClusterShardingSettings(system)
|
val settings: ClusterShardingSettings = ClusterShardingSettings(system)
|
||||||
val configuredIdleTimeout: FiniteDuration = settings.passivationStrategySettings.idleSettings.timeout
|
val configuredIdleTimeout: FiniteDuration =
|
||||||
val configuredLeastRecentlyUsedLimit: Int = settings.passivationStrategySettings.leastRecentlyUsedSettings.limit
|
settings.passivationStrategySettings.idleEntitySettings.fold(Duration.Zero)(_.timeout)
|
||||||
|
val configuredActiveEntityLimit: Int = settings.passivationStrategySettings.activeEntityLimit.getOrElse(0)
|
||||||
|
|
||||||
val probes: Map[Int, TestProbe] = (1 to expectedEntities).map(id => id -> TestProbe()).toMap
|
val probes: Map[Int, TestProbe] = (1 to expectedEntities).map(id => id -> TestProbe()).toMap
|
||||||
val probeRefs: Map[String, ActorRef] = probes.map { case (id, probe) => id.toString -> probe.ref }
|
val probeRefs: Map[String, ActorRef] = probes.map { case (id, probe) => id.toString -> probe.ref }
|
||||||
|
|
@ -137,7 +137,7 @@ class DisabledEntityPassivationSpec
|
||||||
val region = start()
|
val region = start()
|
||||||
region ! Envelope(shard = 1, id = 1, message = "A")
|
region ! Envelope(shard = 1, id = 1, message = "A")
|
||||||
expectReceived(id = 1, message = "A")
|
expectReceived(id = 1, message = "A")
|
||||||
expectNoMessage(id = 1, configuredIdleTimeout * 2)
|
expectNoMessage(id = 1, 1.second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,7 @@ object IdleSpec {
|
||||||
val config: Config = ConfigFactory.parseString("""
|
val config: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = idle
|
default-idle-strategy.idle-entity.timeout = 1s
|
||||||
idle.timeout = 1s
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""").withFallback(EntityPassivationSpec.config)
|
""").withFallback(EntityPassivationSpec.config)
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,11 @@ object LeastFrequentlyUsedSpec {
|
||||||
val config: Config = ConfigFactory.parseString("""
|
val config: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = least-frequently-used
|
strategy = lfu
|
||||||
least-frequently-used.limit = 10
|
lfu {
|
||||||
|
active-entity-limit = 10
|
||||||
|
replacement.policy = least-frequently-used
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""").withFallback(EntityPassivationSpec.config)
|
""").withFallback(EntityPassivationSpec.config)
|
||||||
|
|
@ -23,10 +26,15 @@ object LeastFrequentlyUsedSpec {
|
||||||
val dynamicAgingConfig: Config = ConfigFactory.parseString("""
|
val dynamicAgingConfig: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = least-frequently-used
|
strategy = lfuda
|
||||||
least-frequently-used {
|
lfuda {
|
||||||
limit = 10
|
active-entity-limit = 10
|
||||||
dynamic-aging = on
|
replacement {
|
||||||
|
policy = least-frequently-used
|
||||||
|
least-frequently-used {
|
||||||
|
dynamic-aging = on
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -35,17 +43,18 @@ object LeastFrequentlyUsedSpec {
|
||||||
val idleConfig: Config = ConfigFactory.parseString("""
|
val idleConfig: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = least-frequently-used
|
strategy = lfu-idle
|
||||||
least-frequently-used {
|
lfu-idle {
|
||||||
limit = 3
|
active-entity-limit = 3
|
||||||
idle.timeout = 1s
|
replacement.policy = least-frequently-used
|
||||||
|
idle-entity.timeout = 1s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""").withFallback(EntityPassivationSpec.config)
|
""").withFallback(EntityPassivationSpec.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
class LeastFrequentlyUsedEntityPassivationSpec
|
class LeastFrequentlyUsedSpec
|
||||||
extends AbstractEntityPassivationSpec(LeastFrequentlyUsedSpec.config, expectedEntities = 40) {
|
extends AbstractEntityPassivationSpec(LeastFrequentlyUsedSpec.config, expectedEntities = 40) {
|
||||||
|
|
||||||
import EntityPassivationSpec.Entity.Envelope
|
import EntityPassivationSpec.Entity.Envelope
|
||||||
|
|
@ -196,7 +205,7 @@ class LeastFrequentlyUsedEntityPassivationSpec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LeastFrequentlyUsedWithDynamicAgingEntityPassivationSpec
|
class LeastFrequentlyUsedWithDynamicAgingSpec
|
||||||
extends AbstractEntityPassivationSpec(LeastFrequentlyUsedSpec.dynamicAgingConfig, expectedEntities = 21) {
|
extends AbstractEntityPassivationSpec(LeastFrequentlyUsedSpec.dynamicAgingConfig, expectedEntities = 21) {
|
||||||
|
|
||||||
import EntityPassivationSpec.Entity.Envelope
|
import EntityPassivationSpec.Entity.Envelope
|
||||||
|
|
@ -273,7 +282,7 @@ class LeastFrequentlyUsedWithDynamicAgingEntityPassivationSpec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LeastFrequentlyUsedWithIdleEntityPassivationSpec
|
class LeastFrequentlyUsedWithIdleSpec
|
||||||
extends AbstractEntityPassivationSpec(LeastFrequentlyUsedSpec.idleConfig, expectedEntities = 3) {
|
extends AbstractEntityPassivationSpec(LeastFrequentlyUsedSpec.idleConfig, expectedEntities = 3) {
|
||||||
|
|
||||||
import EntityPassivationSpec.Entity.Envelope
|
import EntityPassivationSpec.Entity.Envelope
|
||||||
|
|
@ -283,19 +292,17 @@ class LeastFrequentlyUsedWithIdleEntityPassivationSpec
|
||||||
"passivate entities when they haven't seen messages for the configured timeout" in {
|
"passivate entities when they haven't seen messages for the configured timeout" in {
|
||||||
val region = start()
|
val region = start()
|
||||||
|
|
||||||
val idleTimeout = settings.passivationStrategySettings.leastFrequentlyUsedSettings.idleSettings.get.timeout
|
|
||||||
|
|
||||||
val lastSendNanoTime1 = System.nanoTime()
|
val lastSendNanoTime1 = System.nanoTime()
|
||||||
region ! Envelope(shard = 1, id = 1, message = "A")
|
region ! Envelope(shard = 1, id = 1, message = "A")
|
||||||
region ! Envelope(shard = 1, id = 2, message = "B")
|
region ! Envelope(shard = 1, id = 2, message = "B")
|
||||||
|
|
||||||
// keep entity 3 active to prevent idle passivation
|
// keep entity 3 active to prevent idle passivation
|
||||||
region ! Envelope(shard = 1, id = 3, message = "C")
|
region ! Envelope(shard = 1, id = 3, message = "C")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
region ! Envelope(shard = 1, id = 3, message = "D")
|
region ! Envelope(shard = 1, id = 3, message = "D")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
region ! Envelope(shard = 1, id = 3, message = "E")
|
region ! Envelope(shard = 1, id = 3, message = "E")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
val lastSendNanoTime2 = System.nanoTime()
|
val lastSendNanoTime2 = System.nanoTime()
|
||||||
region ! Envelope(shard = 1, id = 3, message = "F")
|
region ! Envelope(shard = 1, id = 3, message = "F")
|
||||||
|
|
||||||
|
|
@ -307,13 +314,13 @@ class LeastFrequentlyUsedWithIdleEntityPassivationSpec
|
||||||
expectReceived(id = 3, message = "F")
|
expectReceived(id = 3, message = "F")
|
||||||
val passivate1 = expectReceived(id = 1, message = Stop)
|
val passivate1 = expectReceived(id = 1, message = Stop)
|
||||||
val passivate2 = expectReceived(id = 2, message = Stop)
|
val passivate2 = expectReceived(id = 2, message = Stop)
|
||||||
val passivate3 = expectReceived(id = 3, message = Stop, within = idleTimeout * 2)
|
val passivate3 = expectReceived(id = 3, message = Stop, within = configuredIdleTimeout * 2)
|
||||||
|
|
||||||
// note: touched timestamps are when the shard receives the message, not the entity itself
|
// note: touched timestamps are when the shard receives the message, not the entity itself
|
||||||
// so look at the time from before sending the last message until receiving the passivate message
|
// so look at the time from before sending the last message until receiving the passivate message
|
||||||
(passivate1.nanoTime - lastSendNanoTime1).nanos should be > idleTimeout
|
(passivate1.nanoTime - lastSendNanoTime1).nanos should be > configuredIdleTimeout
|
||||||
(passivate2.nanoTime - lastSendNanoTime1).nanos should be > idleTimeout
|
(passivate2.nanoTime - lastSendNanoTime1).nanos should be > configuredIdleTimeout
|
||||||
(passivate3.nanoTime - lastSendNanoTime2).nanos should be > idleTimeout
|
(passivate3.nanoTime - lastSendNanoTime2).nanos should be > configuredIdleTimeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,11 @@ object LeastRecentlyUsedSpec {
|
||||||
val config: Config = ConfigFactory.parseString("""
|
val config: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = least-recently-used
|
strategy = lru
|
||||||
least-recently-used.limit = 10
|
lru {
|
||||||
|
active-entity-limit = 10
|
||||||
|
replacement.policy = least-recently-used
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""").withFallback(EntityPassivationSpec.config)
|
""").withFallback(EntityPassivationSpec.config)
|
||||||
|
|
@ -23,12 +26,17 @@ object LeastRecentlyUsedSpec {
|
||||||
val segmentedConfig: Config = ConfigFactory.parseString("""
|
val segmentedConfig: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = least-recently-used
|
strategy = slru
|
||||||
least-recently-used {
|
slru {
|
||||||
limit = 10
|
active-entity-limit = 10
|
||||||
segmented {
|
replacement {
|
||||||
levels = 2
|
policy = least-recently-used
|
||||||
proportions = [0.2, 0.8]
|
least-recently-used {
|
||||||
|
segmented {
|
||||||
|
levels = 2
|
||||||
|
proportions = [0.2, 0.8]
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -38,10 +46,11 @@ object LeastRecentlyUsedSpec {
|
||||||
val idleConfig: Config = ConfigFactory.parseString("""
|
val idleConfig: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = least-recently-used
|
strategy = lru-idle
|
||||||
least-recently-used {
|
lru-idle {
|
||||||
limit = 3
|
active-entity-limit = 3
|
||||||
idle.timeout = 1s
|
replacement.policy = least-recently-used
|
||||||
|
idle-entity.timeout = 1s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -238,19 +247,17 @@ class LeastRecentlyUsedWithIdleSpec
|
||||||
"passivate entities when they haven't seen messages for the configured timeout" in {
|
"passivate entities when they haven't seen messages for the configured timeout" in {
|
||||||
val region = start()
|
val region = start()
|
||||||
|
|
||||||
val idleTimeout = settings.passivationStrategySettings.leastRecentlyUsedSettings.idleSettings.get.timeout
|
|
||||||
|
|
||||||
val lastSendNanoTime1 = System.nanoTime()
|
val lastSendNanoTime1 = System.nanoTime()
|
||||||
region ! Envelope(shard = 1, id = 1, message = "A")
|
region ! Envelope(shard = 1, id = 1, message = "A")
|
||||||
region ! Envelope(shard = 1, id = 2, message = "B")
|
region ! Envelope(shard = 1, id = 2, message = "B")
|
||||||
|
|
||||||
// keep entity 3 active to prevent idle passivation
|
// keep entity 3 active to prevent idle passivation
|
||||||
region ! Envelope(shard = 1, id = 3, message = "C")
|
region ! Envelope(shard = 1, id = 3, message = "C")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
region ! Envelope(shard = 1, id = 3, message = "D")
|
region ! Envelope(shard = 1, id = 3, message = "D")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
region ! Envelope(shard = 1, id = 3, message = "E")
|
region ! Envelope(shard = 1, id = 3, message = "E")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
val lastSendNanoTime2 = System.nanoTime()
|
val lastSendNanoTime2 = System.nanoTime()
|
||||||
region ! Envelope(shard = 1, id = 3, message = "F")
|
region ! Envelope(shard = 1, id = 3, message = "F")
|
||||||
|
|
||||||
|
|
@ -262,13 +269,13 @@ class LeastRecentlyUsedWithIdleSpec
|
||||||
expectReceived(id = 3, message = "F")
|
expectReceived(id = 3, message = "F")
|
||||||
val passivate1 = expectReceived(id = 1, message = Stop)
|
val passivate1 = expectReceived(id = 1, message = Stop)
|
||||||
val passivate2 = expectReceived(id = 2, message = Stop)
|
val passivate2 = expectReceived(id = 2, message = Stop)
|
||||||
val passivate3 = expectReceived(id = 3, message = Stop, within = idleTimeout * 2)
|
val passivate3 = expectReceived(id = 3, message = Stop, within = configuredIdleTimeout * 2)
|
||||||
|
|
||||||
// note: touched timestamps are when the shard receives the message, not the entity itself
|
// note: touched timestamps are when the shard receives the message, not the entity itself
|
||||||
// so look at the time from before sending the last message until receiving the passivate message
|
// so look at the time from before sending the last message until receiving the passivate message
|
||||||
(passivate1.nanoTime - lastSendNanoTime1).nanos should be > idleTimeout
|
(passivate1.nanoTime - lastSendNanoTime1).nanos should be > configuredIdleTimeout
|
||||||
(passivate2.nanoTime - lastSendNanoTime1).nanos should be > idleTimeout
|
(passivate2.nanoTime - lastSendNanoTime1).nanos should be > configuredIdleTimeout
|
||||||
(passivate3.nanoTime - lastSendNanoTime2).nanos should be > idleTimeout
|
(passivate3.nanoTime - lastSendNanoTime2).nanos should be > configuredIdleTimeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,11 @@ object MostRecentlyUsedSpec {
|
||||||
val config: Config = ConfigFactory.parseString("""
|
val config: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = most-recently-used
|
strategy = mru
|
||||||
most-recently-used.limit = 10
|
mru {
|
||||||
|
active-entity-limit = 10
|
||||||
|
replacement.policy = most-recently-used
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
""").withFallback(EntityPassivationSpec.config)
|
""").withFallback(EntityPassivationSpec.config)
|
||||||
|
|
@ -23,10 +26,11 @@ object MostRecentlyUsedSpec {
|
||||||
val idleConfig: Config = ConfigFactory.parseString("""
|
val idleConfig: Config = ConfigFactory.parseString("""
|
||||||
akka.cluster.sharding {
|
akka.cluster.sharding {
|
||||||
passivation {
|
passivation {
|
||||||
strategy = most-recently-used
|
strategy = mru-idle
|
||||||
most-recently-used {
|
mru-idle {
|
||||||
limit = 3
|
active-entity-limit = 3
|
||||||
idle.timeout = 1s
|
replacement.policy = most-recently-used
|
||||||
|
idle-entity.timeout = 1s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +145,7 @@ class MostRecentlyUsedSpec extends AbstractEntityPassivationSpec(MostRecentlyUse
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MostRecentlyUsedWithIdleEntityPassivationSpec
|
class MostRecentlyUsedWithIdleSpec
|
||||||
extends AbstractEntityPassivationSpec(MostRecentlyUsedSpec.idleConfig, expectedEntities = 3) {
|
extends AbstractEntityPassivationSpec(MostRecentlyUsedSpec.idleConfig, expectedEntities = 3) {
|
||||||
|
|
||||||
import EntityPassivationSpec.Entity.Envelope
|
import EntityPassivationSpec.Entity.Envelope
|
||||||
|
|
@ -151,19 +155,17 @@ class MostRecentlyUsedWithIdleEntityPassivationSpec
|
||||||
"passivate entities when they haven't seen messages for the configured timeout" in {
|
"passivate entities when they haven't seen messages for the configured timeout" in {
|
||||||
val region = start()
|
val region = start()
|
||||||
|
|
||||||
val idleTimeout = settings.passivationStrategySettings.mostRecentlyUsedSettings.idleSettings.get.timeout
|
|
||||||
|
|
||||||
val lastSendNanoTime1 = System.nanoTime()
|
val lastSendNanoTime1 = System.nanoTime()
|
||||||
region ! Envelope(shard = 1, id = 1, message = "A")
|
region ! Envelope(shard = 1, id = 1, message = "A")
|
||||||
region ! Envelope(shard = 1, id = 2, message = "B")
|
region ! Envelope(shard = 1, id = 2, message = "B")
|
||||||
|
|
||||||
// keep entity 3 active to prevent idle passivation
|
// keep entity 3 active to prevent idle passivation
|
||||||
region ! Envelope(shard = 1, id = 3, message = "C")
|
region ! Envelope(shard = 1, id = 3, message = "C")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
region ! Envelope(shard = 1, id = 3, message = "D")
|
region ! Envelope(shard = 1, id = 3, message = "D")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
region ! Envelope(shard = 1, id = 3, message = "E")
|
region ! Envelope(shard = 1, id = 3, message = "E")
|
||||||
Thread.sleep((idleTimeout / 2).toMillis)
|
Thread.sleep((configuredIdleTimeout / 2).toMillis)
|
||||||
val lastSendNanoTime2 = System.nanoTime()
|
val lastSendNanoTime2 = System.nanoTime()
|
||||||
region ! Envelope(shard = 1, id = 3, message = "F")
|
region ! Envelope(shard = 1, id = 3, message = "F")
|
||||||
|
|
||||||
|
|
@ -175,13 +177,13 @@ class MostRecentlyUsedWithIdleEntityPassivationSpec
|
||||||
expectReceived(id = 3, message = "F")
|
expectReceived(id = 3, message = "F")
|
||||||
val passivate1 = expectReceived(id = 1, message = Stop)
|
val passivate1 = expectReceived(id = 1, message = Stop)
|
||||||
val passivate2 = expectReceived(id = 2, message = Stop)
|
val passivate2 = expectReceived(id = 2, message = Stop)
|
||||||
val passivate3 = expectReceived(id = 3, message = Stop, within = idleTimeout * 2)
|
val passivate3 = expectReceived(id = 3, message = Stop, within = configuredIdleTimeout * 2)
|
||||||
|
|
||||||
// note: touched timestamps are when the shard receives the message, not the entity itself
|
// note: touched timestamps are when the shard receives the message, not the entity itself
|
||||||
// so look at the time from before sending the last message until receiving the passivate message
|
// so look at the time from before sending the last message until receiving the passivate message
|
||||||
(passivate1.nanoTime - lastSendNanoTime1).nanos should be > idleTimeout
|
(passivate1.nanoTime - lastSendNanoTime1).nanos should be > configuredIdleTimeout
|
||||||
(passivate2.nanoTime - lastSendNanoTime1).nanos should be > idleTimeout
|
(passivate2.nanoTime - lastSendNanoTime1).nanos should be > configuredIdleTimeout
|
||||||
(passivate3.nanoTime - lastSendNanoTime2).nanos should be > idleTimeout
|
(passivate3.nanoTime - lastSendNanoTime2).nanos should be > configuredIdleTimeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,10 @@ The stop message is only sent locally, from the shard to the entity so does not
|
||||||
## Automatic Passivation
|
## Automatic Passivation
|
||||||
|
|
||||||
Entities are automatically passivated based on a passivation strategy. The default passivation strategy is to
|
Entities are automatically passivated based on a passivation strategy. The default passivation strategy is to
|
||||||
passivate idle entities when they haven't received a message within a specified interval.
|
[passivate idle entities](#idle-entity-passivation) when they haven't received a message within a specified interval,
|
||||||
|
and this is the current default strategy to maintain compatibility with earlier versions. It's recommended to switch to
|
||||||
|
a [passivation strategy with an active entity limit](#active-entity-limits) and a pre-configured default strategy is
|
||||||
|
provided. Active entity limits and idle entity timeouts can also be used together.
|
||||||
|
|
||||||
Automatic passivation can be disabled by setting `akka.cluster.sharding.passivation.strategy = none`. It is disabled
|
Automatic passivation can be disabled by setting `akka.cluster.sharding.passivation.strategy = none`. It is disabled
|
||||||
automatically if @ref:[Remembering Entities](#remembering-entities) is enabled.
|
automatically if @ref:[Remembering Entities](#remembering-entities) is enabled.
|
||||||
|
|
@ -301,34 +304,78 @@ directly to the `ActorRef`, including messages that the actor sends to itself, a
|
||||||
|
|
||||||
@@@
|
@@@
|
||||||
|
|
||||||
Supported passivation strategies are:
|
### Idle entity passivation
|
||||||
|
|
||||||
### Idle passivation strategy
|
Idle entities can be automatically passivated when they have not received a message for a specified length of time.
|
||||||
|
This is currently the default strategy, for compatibility, and is enabled automatically with a timeout of 2 minutes.
|
||||||
The **idle** passivation strategy passivates entities when they have not received a message for a specified length of
|
Specify a different idle timeout with configuration:
|
||||||
time. This is the default strategy and is enabled automatically with a timeout of 2 minutes. Specify a different idle
|
|
||||||
timeout with configuration:
|
|
||||||
|
|
||||||
@@snip [passivation idle timeout](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-idle-timeout type=conf }
|
@@snip [passivation idle timeout](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-idle-timeout type=conf }
|
||||||
|
|
||||||
Or specify the idle timeout as a duration using the `withIdlePassivationStrategy` method on `ClusterShardingSettings`.
|
Or specify the idle timeout as a duration using the `withPassivationStrategy` method on `ClusterShardingSettings`.
|
||||||
|
|
||||||
### Least recently used passivation strategy
|
Idle entity timeouts can be enabled and configured for any passivation strategy.
|
||||||
|
|
||||||
The **least recently used** passivation strategy passivates those entities that have the least recent activity when the
|
### Active entity limits
|
||||||
number of active entities passes a specified limit. The configurable limit is for a whole shard region and is divided
|
|
||||||
evenly among the active shards in each region. Configure automatic passivation to use the least recently used
|
|
||||||
passivation strategy, and set the limit for active entities in a shard region:
|
|
||||||
|
|
||||||
@@snip [passivation least recently used](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-least-recently-used type=conf }
|
Automatic passivation strategies can limit the number of active entities. Limit-based passivation strategies use a
|
||||||
|
replacement policy to determine which active entities should be passivated when the active entity limit is exceeded.
|
||||||
|
The configurable limit is for a whole shard region and is divided evenly among the active shards in each region.
|
||||||
|
|
||||||
Or enable the least recently used passivation strategy and set the active entity limit using the
|
A recommended passivation strategy, which will become the new default passivation strategy in future versions of Akka
|
||||||
`withLeastRecentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
Cluster Sharding, can be enabled with configuration:
|
||||||
|
|
||||||
#### Segmented least recently used strategy
|
@@snip [passivation new default strategy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-new-default-strategy type=conf }
|
||||||
|
|
||||||
A variation of the least recently used passivation strategy can be enabled that divides the active entity space into
|
This default strategy uses a [segmented least recently used policy](#segmented-least-recently-used-policy). The active
|
||||||
multiple segments to introduce frequency information into the strategy. Higher-level segments contain entities that
|
entity limit can be configured:
|
||||||
|
|
||||||
|
@@snip [passivation new default strategy configured](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-new-default-strategy-configured type=conf }
|
||||||
|
|
||||||
|
Or using the `withActiveEntityLimit` method on `ClusterShardingSettings.PassivationStrategySettings`.
|
||||||
|
|
||||||
|
An [idle entity timeout](#idle-entity-passivation) can also be enabled and configured for this strategy:
|
||||||
|
|
||||||
|
@@snip [passivation new default strategy with idle](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-new-default-strategy-with-idle type=conf }
|
||||||
|
|
||||||
|
Or using the `withIdleEntityPassivation` method on `ClusterShardingSettings.PassivationStrategySettings`.
|
||||||
|
|
||||||
|
If the default strategy is not appropriate for particular workloads and access patterns, a [custom passivation
|
||||||
|
strategy](#custom-passivation-strategies) can be created with configurable replacement policies, active entity limits,
|
||||||
|
and idle entity timeouts.
|
||||||
|
|
||||||
|
### Custom passivation strategies
|
||||||
|
|
||||||
|
To configure a custom passivation strategy, create a configuration section for the strategy under
|
||||||
|
`akka.cluster.sharding.passivation` and select this strategy using the `strategy` setting. The strategy needs a
|
||||||
|
_replacement policy_ to be chosen, an _active entity limit_ to be set, and can optionally [passivate idle
|
||||||
|
entities](#idle-entity-passivation). For example, a custom strategy can be configured to use the [least recently used
|
||||||
|
policy](#least-recently-used-policy):
|
||||||
|
|
||||||
|
@@snip [custom passivation strategy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #custom-passivation-strategy type=conf }
|
||||||
|
|
||||||
|
The active entity limit and replacement policy can also be configured using the `withPassivationStrategy` method on
|
||||||
|
`ClusterShardingSettings`, passing custom `ClusterShardingSettings.PassivationStrategySettings`.
|
||||||
|
|
||||||
|
### Least recently used policy
|
||||||
|
|
||||||
|
The **least recently used** policy passivates those entities that have the least recent activity when the number of
|
||||||
|
active entities passes the specified limit.
|
||||||
|
|
||||||
|
**When to use**: the least recently used policy should be used when access patterns are recency biased, where entities
|
||||||
|
that were recently accessed are likely to be accessed again. See the [segmented least recently used
|
||||||
|
policy](#segmented-least-recently-used-policy) for a variation that also distinguishes frequency of access.
|
||||||
|
|
||||||
|
Configure a passivation strategy to use the least recently used policy:
|
||||||
|
|
||||||
|
@@snip [LRU policy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #lru-policy type=conf }
|
||||||
|
|
||||||
|
Or using the `withLeastRecentlyUsedReplacement` method on `ClusterShardingSettings.PassivationStrategySettings`.
|
||||||
|
|
||||||
|
#### Segmented least recently used policy
|
||||||
|
|
||||||
|
A variation of the least recently used policy can be enabled that divides the active entity space into multiple
|
||||||
|
segments to introduce frequency information into the passivation strategy. Higher-level segments contain entities that
|
||||||
have been accessed more often. The first segment is for entities that have only been accessed once, the second segment
|
have been accessed more often. The first segment is for entities that have only been accessed once, the second segment
|
||||||
for entities that have been accessed at least twice, and so on. When an entity is accessed again, it will be promoted
|
for entities that have been accessed at least twice, and so on. When an entity is accessed again, it will be promoted
|
||||||
to the most recent position of the next-level or highest-level segment. The higher-level segments are limited, where
|
to the most recent position of the next-level or highest-level segment. The higher-level segments are limited, where
|
||||||
|
|
@ -338,80 +385,66 @@ to the level below. Only the least recently used entities in the lowest level wi
|
||||||
higher levels are considered "protected", where entities will have additional opportunities to be accessed before being
|
higher levels are considered "protected", where entities will have additional opportunities to be accessed before being
|
||||||
considered for passivation.
|
considered for passivation.
|
||||||
|
|
||||||
To configure a segmented least recently used (SLRU) strategy, with two levels and a protected segment limited to 80% of the total limit:
|
**When to use**: the segmented least recently used policy can be used for workloads where some entities are more
|
||||||
|
popular than others, to prioritize those entities that are accessed more frequently.
|
||||||
|
|
||||||
@@snip [passivation segmented least recently used](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-segmented-least-recently-used type=conf }
|
To configure a segmented least recently used (SLRU) policy, with two levels and a protected segment limited to 80% of
|
||||||
|
the total limit:
|
||||||
|
|
||||||
Or to configure a 4-level segmented least recently used (S4LRU) strategy, with 4 evenly divided levels:
|
@@snip [SLRU policy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #slru-policy type=conf }
|
||||||
|
|
||||||
@@snip [passivation segmented least recently used](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-s4-least-recently-used type=conf }
|
Or to configure a 4-level segmented least recently used (S4LRU) policy, with 4 evenly divided levels:
|
||||||
|
|
||||||
Or using the `withLeastRecentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
@@snip [S4LRU policy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #s4lru-policy type=conf }
|
||||||
|
|
||||||
#### Idle timeouts (with least recently used strategy)
|
Or using custom `ClusterShardingSettings.PassivationStrategySettings.LeastRecentlyUsedSettings`.
|
||||||
|
|
||||||
Passivating idle entities (when they have not received a message for a specified length of time) can also be enabled by configuring the least recently used passivation strategy with an idle timeout:
|
### Most recently used policy
|
||||||
|
|
||||||
@@snip [passivation least recently used with idle](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-least-recently-used-with-idle type=conf }
|
The **most recently used** policy passivates those entities that have the most recent activity when the number of
|
||||||
|
active entities passes the specified limit.
|
||||||
|
|
||||||
Or enable the least recently used passivation strategy with both an active entity limit and an idle timeout using the
|
**When to use**: the most recently used policy is most useful when the older an entity is, the more likely that entity
|
||||||
`withLeastRecentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
will be accessed again; as seen in cyclic access patterns.
|
||||||
|
|
||||||
### Most recently used passivation strategy
|
Configure a passivation strategy to use the most recently used policy:
|
||||||
|
|
||||||
The **most recently used** passivation strategy passivates those entities that have the most recent activity when the
|
@@snip [MRU policy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #mru-policy type=conf }
|
||||||
number of active entities passes a specified limit. The configurable limit is for a whole shard region and is divided
|
|
||||||
evenly among the active shards in each region. This strategy is most useful when the older an entity is, the more
|
|
||||||
likely that entity will be accessed again; as seen in cyclic access patterns. Configure automatic passivation to use
|
|
||||||
the most recently used passivation strategy, and set the limit for active entities in a shard region:
|
|
||||||
|
|
||||||
@@snip [passivation most recently used](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-most-recently-used type=conf }
|
Or using the `withMostRecentlyUsedReplacement` method on `ClusterShardingSettings.PassivationStrategySettings`.
|
||||||
|
|
||||||
Or enable the most recently used passivation strategy and set the active entity limit using the
|
### Least frequently used policy
|
||||||
`withMostRecentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
|
||||||
|
|
||||||
#### Idle timeouts (with most recently used strategy)
|
The **least frequently used** policy passivates those entities that have the least frequent activity when the number of
|
||||||
|
active entities passes the specified limit.
|
||||||
|
|
||||||
Passivating idle entities (when they have not received a message for a specified length of time) can also be enabled by configuring the most recently used passivation strategy with an idle timeout:
|
**When to use**: the least frequently used policy should be used when access patterns are frequency biased, where some
|
||||||
|
entities are much more popular than others and should be prioritized. See the [least frequently used with dynamic aging
|
||||||
|
policy](#least-frequently-used-with-dynamic-aging-policy) for a variation that also handles shifts in popularity.
|
||||||
|
|
||||||
@@snip [passivation most recently used with idle](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-most-recently-used-with-idle type=conf }
|
Configure automatic passivation to use the least frequently used policy:
|
||||||
|
|
||||||
Or enable the most recently used passivation strategy with both an active entity limit and an idle timeout using the
|
@@snip [LFU policy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #lfu-policy type=conf }
|
||||||
`withMostRecentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
|
||||||
|
|
||||||
### Least frequently used passivation strategy
|
Or using the `withLeastFrequentlyUsedReplacement` method on `ClusterShardingSettings.PassivationStrategySettings`.
|
||||||
|
|
||||||
The **least frequently used** passivation strategy passivates those entities that have the least frequent activity when
|
#### Least frequently used with dynamic aging policy
|
||||||
the number of active entities passes a specified limit. The configurable limit is for a whole shard region and is
|
|
||||||
divided evenly among the active shards in each region. Configure automatic passivation to use the least frequently used
|
|
||||||
passivation strategy, and set the limit for active entities in a shard region:
|
|
||||||
|
|
||||||
@@snip [passivation least frequently used](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-least-frequently-used type=conf }
|
A variation of the least frequently used policy can be enabled that uses "dynamic aging" to adapt to shifts in the set
|
||||||
|
of popular entities, which is useful for smaller active entity limits and when shifts in popularity are common. If
|
||||||
|
entities were frequently accessed in the past but then become unpopular, they can still remain active for a long time
|
||||||
|
given their high frequency counts. Dynamic aging effectively increases the frequencies for recently accessed entities
|
||||||
|
so they can more easily become higher priority over entities that are no longer accessed.
|
||||||
|
|
||||||
Or enable the least frequently used passivation strategy and set the active entity limit using the
|
**When to use**: the least frequently used with dynamic aging policy can be used when workloads are frequency biased
|
||||||
`withLeastFrequentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
(there are some entities that are much more popular), but which entities are most popular changes over time. Shifts in
|
||||||
|
popularity can have more impact on a least frequently used policy if the active entity limit is small.
|
||||||
|
|
||||||
#### Dynamic aging for least frequently used strategy
|
Configure dynamic aging with the least frequently used policy:
|
||||||
|
|
||||||
A variation of the least frequently used passivation strategy can be enabled that uses "dynamic aging" to adapt to
|
@@snip [LFUDA policy](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #lfuda-policy type=conf }
|
||||||
shifts in the set of popular entities, which is useful for smaller active entity limits and when shifts in popularity
|
|
||||||
are common. If entities were frequently accessed in the past but then become unpopular, they can still remain active
|
|
||||||
for a long time given their high frequency counts. Dynamic aging effectively increases the frequencies for recently
|
|
||||||
accessed entities so they can more easily become higher priority over entities that are no longer accessed. Configure
|
|
||||||
dynamic aging with the least frequently used passivation strategy:
|
|
||||||
|
|
||||||
@@snip [passivation least frequently used with dynamic aging](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-least-frequently-used-with-dynamic-aging type=conf }
|
Or using custom `ClusterShardingSettings.PassivationStrategySettings.LeastFrequentlyUsedSettings`.
|
||||||
|
|
||||||
Or when using the `withLeastFrequentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
|
||||||
|
|
||||||
#### Idle timeouts (with least frequently used strategy)
|
|
||||||
|
|
||||||
Passivating idle entities (when they have not received a message for a specified length of time) can also be enabled by configuring the least frequently used passivation strategy with an idle timeout:
|
|
||||||
|
|
||||||
@@snip [passivation least frequently used with idle](/akka-cluster-sharding/src/test/scala/akka/cluster/sharding/ClusterShardingSettingsSpec.scala) { #passivation-least-frequently-used-with-idle type=conf }
|
|
||||||
|
|
||||||
Or enable the least frequently used passivation strategy with both an active entity limit and an idle timeout using the
|
|
||||||
`withLeastFrequentlyUsedPassivationStrategy` method on `ClusterShardingSettings`.
|
|
||||||
|
|
||||||
|
|
||||||
## Sharding State
|
## Sharding State
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue