2015-06-07 14:49:38 +02:00
|
|
|
/**
|
2018-01-04 17:26:29 +00:00
|
|
|
* Copyright (C) 2015-2018 Lightbend Inc. <https://www.lightbend.com>
|
2015-06-07 14:49:38 +02:00
|
|
|
*/
|
2018-03-13 23:45:55 +09:00
|
|
|
|
2015-06-07 14:49:38 +02:00
|
|
|
package akka.cluster.sharding
|
|
|
|
|
|
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
|
import scala.concurrent.duration.FiniteDuration
|
|
|
|
|
import akka.actor.ActorSystem
|
|
|
|
|
import akka.actor.NoSerializationVerificationNeeded
|
2018-03-07 05:17:56 +01:00
|
|
|
import akka.annotation.InternalApi
|
2015-06-07 14:49:38 +02:00
|
|
|
import com.typesafe.config.Config
|
2018-03-07 05:17:56 +01:00
|
|
|
import akka.cluster.Cluster
|
2015-06-07 15:34:21 +02:00
|
|
|
import akka.cluster.singleton.ClusterSingletonManagerSettings
|
2015-06-07 14:49:38 +02:00
|
|
|
|
|
|
|
|
object ClusterShardingSettings {
|
2017-01-18 16:28:24 +01:00
|
|
|
|
|
|
|
|
val StateStoreModePersistence = "persistence"
|
|
|
|
|
val StateStoreModeDData = "ddata"
|
|
|
|
|
|
2015-06-07 14:49:38 +02:00
|
|
|
/**
|
|
|
|
|
* Create settings from the default configuration
|
|
|
|
|
* `akka.cluster.sharding`.
|
|
|
|
|
*/
|
|
|
|
|
def apply(system: ActorSystem): ClusterShardingSettings =
|
|
|
|
|
apply(system.settings.config.getConfig("akka.cluster.sharding"))
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Create settings from a configuration with the same layout as
|
|
|
|
|
* the default configuration `akka.cluster.sharding`.
|
|
|
|
|
*/
|
|
|
|
|
def apply(config: Config): ClusterShardingSettings = {
|
|
|
|
|
val tuningParameters = new TuningParameters(
|
|
|
|
|
coordinatorFailureBackoff = config.getDuration("coordinator-failure-backoff", MILLISECONDS).millis,
|
|
|
|
|
retryInterval = config.getDuration("retry-interval", MILLISECONDS).millis,
|
|
|
|
|
bufferSize = config.getInt("buffer-size"),
|
|
|
|
|
handOffTimeout = config.getDuration("handoff-timeout", MILLISECONDS).millis,
|
|
|
|
|
shardStartTimeout = config.getDuration("shard-start-timeout", MILLISECONDS).millis,
|
|
|
|
|
shardFailureBackoff = config.getDuration("shard-failure-backoff", MILLISECONDS).millis,
|
2015-06-09 12:25:58 +02:00
|
|
|
entityRestartBackoff = config.getDuration("entity-restart-backoff", MILLISECONDS).millis,
|
2015-06-07 14:49:38 +02:00
|
|
|
rebalanceInterval = config.getDuration("rebalance-interval", MILLISECONDS).millis,
|
2015-06-08 11:57:12 +02:00
|
|
|
snapshotAfter = config.getInt("snapshot-after"),
|
2017-02-21 16:17:19 +03:00
|
|
|
keepNrOfBatches = config.getInt("keep-nr-of-batches"),
|
2015-06-07 14:49:38 +02:00
|
|
|
leastShardAllocationRebalanceThreshold =
|
|
|
|
|
config.getInt("least-shard-allocation-strategy.rebalance-threshold"),
|
|
|
|
|
leastShardAllocationMaxSimultaneousRebalance =
|
2015-08-20 13:24:39 +03:00
|
|
|
config.getInt("least-shard-allocation-strategy.max-simultaneous-rebalance"),
|
|
|
|
|
waitingForStateTimeout = config.getDuration("waiting-for-state-timeout", MILLISECONDS).millis,
|
2016-08-01 09:46:09 +01:00
|
|
|
updatingStateTimeout = config.getDuration("updating-state-timeout", MILLISECONDS).millis,
|
|
|
|
|
entityRecoveryStrategy = config.getString("entity-recovery-strategy"),
|
|
|
|
|
entityRecoveryConstantRateStrategyFrequency = config.getDuration("entity-recovery-constant-rate-strategy.frequency", MILLISECONDS).millis,
|
|
|
|
|
entityRecoveryConstantRateStrategyNumberOfEntities = config.getInt("entity-recovery-constant-rate-strategy.number-of-entities"))
|
2015-06-07 14:49:38 +02:00
|
|
|
|
2015-06-07 15:34:21 +02:00
|
|
|
val coordinatorSingletonSettings = ClusterSingletonManagerSettings(config.getConfig("coordinator-singleton"))
|
|
|
|
|
|
2015-06-07 14:49:38 +02:00
|
|
|
new ClusterShardingSettings(
|
|
|
|
|
role = roleOption(config.getString("role")),
|
2015-06-09 12:25:58 +02:00
|
|
|
rememberEntities = config.getBoolean("remember-entities"),
|
2015-06-07 14:49:38 +02:00
|
|
|
journalPluginId = config.getString("journal-plugin-id"),
|
|
|
|
|
snapshotPluginId = config.getString("snapshot-plugin-id"),
|
2015-08-20 13:24:39 +03:00
|
|
|
stateStoreMode = config.getString("state-store-mode"),
|
2015-06-07 15:34:21 +02:00
|
|
|
tuningParameters,
|
|
|
|
|
coordinatorSingletonSettings)
|
2015-06-07 14:49:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Java API: Create settings from the default configuration
|
|
|
|
|
* `akka.cluster.sharding`.
|
|
|
|
|
*/
|
|
|
|
|
def create(system: ActorSystem): ClusterShardingSettings = apply(system)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Java API: Create settings from a configuration with the same layout as
|
|
|
|
|
* the default configuration `akka.cluster.sharding`.
|
|
|
|
|
*/
|
|
|
|
|
def create(config: Config): ClusterShardingSettings = apply(config)
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* INTERNAL API
|
|
|
|
|
*/
|
|
|
|
|
private[akka] def roleOption(role: String): Option[String] =
|
|
|
|
|
if (role == "") None else Option(role)
|
|
|
|
|
|
|
|
|
|
class TuningParameters(
|
2016-08-01 09:46:09 +01:00
|
|
|
val coordinatorFailureBackoff: FiniteDuration,
|
|
|
|
|
val retryInterval: FiniteDuration,
|
|
|
|
|
val bufferSize: Int,
|
|
|
|
|
val handOffTimeout: FiniteDuration,
|
|
|
|
|
val shardStartTimeout: FiniteDuration,
|
|
|
|
|
val shardFailureBackoff: FiniteDuration,
|
|
|
|
|
val entityRestartBackoff: FiniteDuration,
|
|
|
|
|
val rebalanceInterval: FiniteDuration,
|
|
|
|
|
val snapshotAfter: Int,
|
2017-02-21 16:17:19 +03:00
|
|
|
val keepNrOfBatches: Int,
|
2016-08-01 09:46:09 +01:00
|
|
|
val leastShardAllocationRebalanceThreshold: Int,
|
|
|
|
|
val leastShardAllocationMaxSimultaneousRebalance: Int,
|
|
|
|
|
val waitingForStateTimeout: FiniteDuration,
|
|
|
|
|
val updatingStateTimeout: FiniteDuration,
|
|
|
|
|
val entityRecoveryStrategy: String,
|
|
|
|
|
val entityRecoveryConstantRateStrategyFrequency: FiniteDuration,
|
|
|
|
|
val entityRecoveryConstantRateStrategyNumberOfEntities: Int) {
|
|
|
|
|
|
|
|
|
|
require(
|
|
|
|
|
entityRecoveryStrategy == "all" || entityRecoveryStrategy == "constant",
|
|
|
|
|
s"Unknown 'entity-recovery-strategy' [$entityRecoveryStrategy], valid values are 'all' or 'constant'")
|
|
|
|
|
|
2017-02-21 16:17:19 +03:00
|
|
|
// included for binary compatibility
|
|
|
|
|
def this(
|
|
|
|
|
coordinatorFailureBackoff: FiniteDuration,
|
|
|
|
|
retryInterval: FiniteDuration,
|
|
|
|
|
bufferSize: Int,
|
|
|
|
|
handOffTimeout: FiniteDuration,
|
|
|
|
|
shardStartTimeout: FiniteDuration,
|
|
|
|
|
shardFailureBackoff: FiniteDuration,
|
|
|
|
|
entityRestartBackoff: FiniteDuration,
|
|
|
|
|
rebalanceInterval: FiniteDuration,
|
|
|
|
|
snapshotAfter: Int,
|
|
|
|
|
leastShardAllocationRebalanceThreshold: Int,
|
|
|
|
|
leastShardAllocationMaxSimultaneousRebalance: Int,
|
|
|
|
|
waitingForStateTimeout: FiniteDuration,
|
|
|
|
|
updatingStateTimeout: FiniteDuration,
|
|
|
|
|
entityRecoveryStrategy: String,
|
|
|
|
|
entityRecoveryConstantRateStrategyFrequency: FiniteDuration,
|
|
|
|
|
entityRecoveryConstantRateStrategyNumberOfEntities: Int) = {
|
|
|
|
|
this(
|
|
|
|
|
coordinatorFailureBackoff,
|
|
|
|
|
retryInterval,
|
|
|
|
|
bufferSize,
|
|
|
|
|
handOffTimeout,
|
|
|
|
|
shardStartTimeout,
|
|
|
|
|
shardFailureBackoff,
|
|
|
|
|
entityRestartBackoff,
|
|
|
|
|
rebalanceInterval,
|
|
|
|
|
snapshotAfter,
|
|
|
|
|
2,
|
|
|
|
|
leastShardAllocationRebalanceThreshold,
|
|
|
|
|
leastShardAllocationMaxSimultaneousRebalance,
|
|
|
|
|
waitingForStateTimeout,
|
|
|
|
|
updatingStateTimeout,
|
|
|
|
|
entityRecoveryStrategy,
|
|
|
|
|
entityRecoveryConstantRateStrategyFrequency,
|
|
|
|
|
entityRecoveryConstantRateStrategyNumberOfEntities)
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-01 09:46:09 +01:00
|
|
|
// included for binary compatibility
|
|
|
|
|
def this(
|
|
|
|
|
coordinatorFailureBackoff: FiniteDuration,
|
|
|
|
|
retryInterval: FiniteDuration,
|
|
|
|
|
bufferSize: Int,
|
|
|
|
|
handOffTimeout: FiniteDuration,
|
|
|
|
|
shardStartTimeout: FiniteDuration,
|
|
|
|
|
shardFailureBackoff: FiniteDuration,
|
|
|
|
|
entityRestartBackoff: FiniteDuration,
|
|
|
|
|
rebalanceInterval: FiniteDuration,
|
|
|
|
|
snapshotAfter: Int,
|
|
|
|
|
leastShardAllocationRebalanceThreshold: Int,
|
|
|
|
|
leastShardAllocationMaxSimultaneousRebalance: Int,
|
|
|
|
|
waitingForStateTimeout: FiniteDuration,
|
|
|
|
|
updatingStateTimeout: FiniteDuration) = {
|
|
|
|
|
this(
|
|
|
|
|
coordinatorFailureBackoff,
|
|
|
|
|
retryInterval,
|
|
|
|
|
bufferSize,
|
|
|
|
|
handOffTimeout,
|
|
|
|
|
shardStartTimeout,
|
|
|
|
|
shardFailureBackoff,
|
|
|
|
|
entityRestartBackoff,
|
|
|
|
|
rebalanceInterval,
|
|
|
|
|
snapshotAfter,
|
|
|
|
|
leastShardAllocationRebalanceThreshold,
|
|
|
|
|
leastShardAllocationMaxSimultaneousRebalance,
|
|
|
|
|
waitingForStateTimeout,
|
|
|
|
|
updatingStateTimeout,
|
|
|
|
|
"all",
|
2016-10-02 15:44:22 +02:00
|
|
|
100.milliseconds,
|
|
|
|
|
5)
|
2016-08-01 09:46:09 +01:00
|
|
|
}
|
|
|
|
|
}
|
2015-06-07 14:49:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2015-06-09 12:25:58 +02:00
|
|
|
* @param role specifies that this entity type requires cluster nodes with a specific role.
|
2015-06-07 14:49:38 +02:00
|
|
|
* If the role is not specified all nodes in the cluster are used.
|
2015-06-09 12:25:58 +02:00
|
|
|
* @param rememberEntities true if active entity actors shall be automatically restarted upon `Shard`
|
2015-06-07 14:49:38 +02:00
|
|
|
* restart. i.e. if the `Shard` is started on a different `ShardRegion` due to rebalance or crash.
|
2015-06-09 12:25:58 +02:00
|
|
|
* @param journalPluginId Absolute path to the journal plugin configuration entity that is to
|
2015-06-07 14:49:38 +02:00
|
|
|
* be used for the internal persistence of ClusterSharding. If not defined the default
|
2015-06-09 12:25:58 +02:00
|
|
|
* journal plugin is used. Note that this is not related to persistence used by the entity
|
2015-06-07 14:49:38 +02:00
|
|
|
* actors.
|
2015-06-09 12:25:58 +02:00
|
|
|
* @param snapshotPluginId Absolute path to the snapshot plugin configuration entity that is to
|
2015-06-07 14:49:38 +02:00
|
|
|
* be used for the internal persistence of ClusterSharding. If not defined the default
|
2015-06-09 12:25:58 +02:00
|
|
|
* snapshot plugin is used. Note that this is not related to persistence used by the entity
|
2015-06-07 14:49:38 +02:00
|
|
|
* actors.
|
|
|
|
|
* @param tuningParameters additional tuning parameters, see descriptions in reference.conf
|
|
|
|
|
*/
|
|
|
|
|
final class ClusterShardingSettings(
|
2016-06-02 14:06:57 +02:00
|
|
|
val role: Option[String],
|
|
|
|
|
val rememberEntities: Boolean,
|
|
|
|
|
val journalPluginId: String,
|
|
|
|
|
val snapshotPluginId: String,
|
|
|
|
|
val stateStoreMode: String,
|
|
|
|
|
val tuningParameters: ClusterShardingSettings.TuningParameters,
|
2015-06-07 15:34:21 +02:00
|
|
|
val coordinatorSingletonSettings: ClusterSingletonManagerSettings) extends NoSerializationVerificationNeeded {
|
2015-06-07 14:49:38 +02:00
|
|
|
|
2017-01-18 16:28:24 +01:00
|
|
|
import ClusterShardingSettings.{ StateStoreModePersistence, StateStoreModeDData }
|
2016-06-02 14:06:57 +02:00
|
|
|
require(
|
2017-01-18 16:28:24 +01:00
|
|
|
stateStoreMode == StateStoreModePersistence || stateStoreMode == StateStoreModeDData,
|
|
|
|
|
s"Unknown 'state-store-mode' [$stateStoreMode], valid values are '$StateStoreModeDData' or '$StateStoreModePersistence'")
|
2015-08-21 09:53:53 +02:00
|
|
|
|
2018-03-07 05:17:56 +01:00
|
|
|
/** If true, this node should run the shard region, otherwise just a shard proxy should started on this node. */
|
|
|
|
|
@InternalApi
|
|
|
|
|
private[akka] def shouldHostShard(cluster: Cluster): Boolean =
|
|
|
|
|
role.forall(cluster.selfMember.roles.contains)
|
|
|
|
|
|
2015-06-07 14:49:38 +02:00
|
|
|
def withRole(role: String): ClusterShardingSettings = copy(role = ClusterShardingSettings.roleOption(role))
|
|
|
|
|
|
|
|
|
|
def withRole(role: Option[String]): ClusterShardingSettings = copy(role = role)
|
|
|
|
|
|
2015-06-09 12:25:58 +02:00
|
|
|
def withRememberEntities(rememberEntities: Boolean): ClusterShardingSettings =
|
|
|
|
|
copy(rememberEntities = rememberEntities)
|
2015-06-07 14:49:38 +02:00
|
|
|
|
|
|
|
|
def withJournalPluginId(journalPluginId: String): ClusterShardingSettings =
|
|
|
|
|
copy(journalPluginId = journalPluginId)
|
|
|
|
|
|
|
|
|
|
def withSnapshotPluginId(snapshotPluginId: String): ClusterShardingSettings =
|
|
|
|
|
copy(snapshotPluginId = snapshotPluginId)
|
|
|
|
|
|
|
|
|
|
def withTuningParameters(tuningParameters: ClusterShardingSettings.TuningParameters): ClusterShardingSettings =
|
|
|
|
|
copy(tuningParameters = tuningParameters)
|
|
|
|
|
|
2016-04-18 11:37:56 +02:00
|
|
|
def withStateStoreMode(stateStoreMode: String): ClusterShardingSettings =
|
|
|
|
|
copy(stateStoreMode = stateStoreMode)
|
|
|
|
|
|
2015-12-18 11:15:06 +01:00
|
|
|
/**
|
|
|
|
|
* The `role` of the `ClusterSingletonManagerSettings` is not used. The `role` of the
|
|
|
|
|
* coordinator singleton will be the same as the `role` of `ClusterShardingSettings`.
|
|
|
|
|
*/
|
2015-06-07 15:34:21 +02:00
|
|
|
def withCoordinatorSingletonSettings(coordinatorSingletonSettings: ClusterSingletonManagerSettings): ClusterShardingSettings =
|
|
|
|
|
copy(coordinatorSingletonSettings = coordinatorSingletonSettings)
|
|
|
|
|
|
2016-06-02 14:06:57 +02:00
|
|
|
private def copy(
|
|
|
|
|
role: Option[String] = role,
|
|
|
|
|
rememberEntities: Boolean = rememberEntities,
|
|
|
|
|
journalPluginId: String = journalPluginId,
|
|
|
|
|
snapshotPluginId: String = snapshotPluginId,
|
|
|
|
|
stateStoreMode: String = stateStoreMode,
|
|
|
|
|
tuningParameters: ClusterShardingSettings.TuningParameters = tuningParameters,
|
|
|
|
|
coordinatorSingletonSettings: ClusterSingletonManagerSettings = coordinatorSingletonSettings): ClusterShardingSettings =
|
2015-06-07 14:49:38 +02:00
|
|
|
new ClusterShardingSettings(
|
|
|
|
|
role,
|
2015-06-09 12:25:58 +02:00
|
|
|
rememberEntities,
|
2015-06-07 14:49:38 +02:00
|
|
|
journalPluginId,
|
|
|
|
|
snapshotPluginId,
|
2015-08-20 13:24:39 +03:00
|
|
|
stateStoreMode,
|
2015-06-07 15:34:21 +02:00
|
|
|
tuningParameters,
|
|
|
|
|
coordinatorSingletonSettings)
|
2015-06-07 14:49:38 +02:00
|
|
|
}
|