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:
Patrik Nordwall 2013-03-14 20:32:43 +01:00
parent 6e8125a46e
commit 7eac88f372
49 changed files with 870 additions and 481 deletions

View file

@ -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)
}
}