Cluster node roles, see #3049
* Config of node roles cluster.role * Cluster router configurable with use-role * RoleLeaderChanged event * Cluster singleton per role * Cluster only starts once all required per-role node counts are reached, role.<role-name>.min-nr-of-members config * Update documentation and make use of the roles in the examples
This commit is contained in:
parent
6e8125a46e
commit
7eac88f372
49 changed files with 870 additions and 481 deletions
|
|
@ -74,26 +74,31 @@ object ClusterRouterSettings {
|
|||
/**
|
||||
* Settings for create and deploy of the routees
|
||||
*/
|
||||
def apply(totalInstances: Int, maxInstancesPerNode: Int, allowLocalRoutees: Boolean): ClusterRouterSettings =
|
||||
new ClusterRouterSettings(totalInstances, maxInstancesPerNode, allowLocalRoutees)
|
||||
def apply(totalInstances: Int, maxInstancesPerNode: Int, allowLocalRoutees: Boolean, useRole: Option[String]): ClusterRouterSettings =
|
||||
new ClusterRouterSettings(totalInstances, maxInstancesPerNode, routeesPath = "", allowLocalRoutees, useRole)
|
||||
|
||||
/**
|
||||
* Settings for remote deployment of the routees, allowed to use routees on own node
|
||||
*/
|
||||
def apply(totalInstances: Int, maxInstancesPerNode: Int): ClusterRouterSettings =
|
||||
apply(totalInstances, maxInstancesPerNode, allowLocalRoutees = true)
|
||||
def apply(totalInstances: Int, maxInstancesPerNode: Int, useRole: Option[String]): ClusterRouterSettings =
|
||||
apply(totalInstances, maxInstancesPerNode, allowLocalRoutees = true, useRole)
|
||||
|
||||
/**
|
||||
* Settings for lookup of the routees
|
||||
*/
|
||||
def apply(totalInstances: Int, routeesPath: String, allowLocalRoutees: Boolean): ClusterRouterSettings =
|
||||
new ClusterRouterSettings(totalInstances, routeesPath, allowLocalRoutees)
|
||||
def apply(totalInstances: Int, routeesPath: String, allowLocalRoutees: Boolean, useRole: Option[String]): ClusterRouterSettings =
|
||||
new ClusterRouterSettings(totalInstances, maxInstancesPerNode = 1, routeesPath, allowLocalRoutees, useRole)
|
||||
|
||||
/**
|
||||
* Settings for lookup of the routees, allowed to use routees on own node
|
||||
*/
|
||||
def apply(totalInstances: Int, routeesPath: String): ClusterRouterSettings =
|
||||
apply(totalInstances, routeesPath, allowLocalRoutees = true)
|
||||
def apply(totalInstances: Int, routeesPath: String, useRole: Option[String]): ClusterRouterSettings =
|
||||
apply(totalInstances, routeesPath, allowLocalRoutees = true, useRole)
|
||||
|
||||
def useRoleOption(role: String): Option[String] = role match {
|
||||
case null | "" ⇒ None
|
||||
case _ ⇒ Some(role)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -106,19 +111,22 @@ case class ClusterRouterSettings private[akka] (
|
|||
totalInstances: Int,
|
||||
maxInstancesPerNode: Int,
|
||||
routeesPath: String,
|
||||
allowLocalRoutees: Boolean) {
|
||||
allowLocalRoutees: Boolean,
|
||||
useRole: Option[String]) {
|
||||
|
||||
/**
|
||||
* Java API: Settings for create and deploy of the routees
|
||||
*/
|
||||
def this(totalInstances: Int, maxInstancesPerNode: Int, allowLocalRoutees: Boolean) =
|
||||
this(totalInstances, maxInstancesPerNode, routeesPath = "", allowLocalRoutees)
|
||||
def this(totalInstances: Int, maxInstancesPerNode: Int, allowLocalRoutees: Boolean, useRole: String) =
|
||||
this(totalInstances, maxInstancesPerNode, routeesPath = "", allowLocalRoutees,
|
||||
ClusterRouterSettings.useRoleOption(useRole))
|
||||
|
||||
/**
|
||||
* Java API: Settings for lookup of the routees
|
||||
*/
|
||||
def this(totalInstances: Int, routeesPath: String, allowLocalRoutees: Boolean) =
|
||||
this(totalInstances, maxInstancesPerNode = 1, routeesPath, allowLocalRoutees)
|
||||
def this(totalInstances: Int, routeesPath: String, allowLocalRoutees: Boolean, useRole: String) =
|
||||
this(totalInstances, maxInstancesPerNode = 1, routeesPath, allowLocalRoutees,
|
||||
ClusterRouterSettings.useRoleOption(useRole))
|
||||
|
||||
if (totalInstances <= 0) throw new IllegalArgumentException("totalInstances of cluster router must be > 0")
|
||||
if (maxInstancesPerNode <= 0) throw new IllegalArgumentException("maxInstancesPerNode of cluster router must be > 0")
|
||||
|
|
@ -220,7 +228,7 @@ private[akka] class ClusterRouteeProvider(
|
|||
private[routing] def availableNodes: immutable.SortedSet[Address] = {
|
||||
import Member.addressOrdering
|
||||
val currentNodes = nodes
|
||||
if (currentNodes.isEmpty && settings.allowLocalRoutees)
|
||||
if (currentNodes.isEmpty && settings.allowLocalRoutees && satisfiesRole(cluster.selfRoles))
|
||||
//use my own node, cluster information not updated yet
|
||||
immutable.SortedSet(cluster.selfAddress)
|
||||
else
|
||||
|
|
@ -236,7 +244,14 @@ private[akka] class ClusterRouteeProvider(
|
|||
}
|
||||
|
||||
private[routing] def isAvailable(m: Member): Boolean =
|
||||
m.status == MemberStatus.Up && (settings.allowLocalRoutees || m.address != cluster.selfAddress)
|
||||
m.status == MemberStatus.Up &&
|
||||
satisfiesRole(m.roles) &&
|
||||
(settings.allowLocalRoutees || m.address != cluster.selfAddress)
|
||||
|
||||
private def satisfiesRole(memberRoles: Set[String]): Boolean = settings.useRole match {
|
||||
case None ⇒ true
|
||||
case Some(r) ⇒ memberRoles.contains(r)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue