Fix leaking this in constructor of Cluster, see #2473

* Major refactoring to remove the need to use special
  Cluster instance for testing. Use default Cluster
  extension instead. Most of it is trivial changes.
* Used failure-detector.implementation-class from config
  to swap to Puppet
* Removed FailureDetectorStrategy, since it doesn't add any value
* Added Cluster.joinSeedNodes to be able to test seedNodes when Addresses
  are unknown before startup time.
* Removed ClusterEnvironment that was passed around among the actors,
  instead they use the ordinary Cluster extension.
* Overall much cleaner design
This commit is contained in:
Patrik Nordwall 2012-09-06 21:48:40 +02:00
parent 806b5efcdf
commit bd6c39178c
33 changed files with 313 additions and 340 deletions

View file

@ -40,19 +40,7 @@ object Cluster extends ExtensionId[Cluster] with ExtensionIdProvider {
override def lookup = Cluster
override def createExtension(system: ExtendedActorSystem): Cluster = {
val clusterSettings = new ClusterSettings(system.settings.config, system.name)
val failureDetector = {
import clusterSettings.{ FailureDetectorImplementationClass fqcn }
system.dynamicAccess.createInstanceFor[FailureDetector](
fqcn, Seq(classOf[ActorSystem] -> system, classOf[ClusterSettings] -> clusterSettings)).fold(
e throw new ConfigurationException("Could not create custom failure detector [" + fqcn + "] due to:" + e.toString),
identity)
}
new Cluster(system, failureDetector)
}
override def createExtension(system: ExtendedActorSystem): Cluster = new Cluster(system)
}
/**
@ -69,7 +57,7 @@ object Cluster extends ExtensionId[Cluster] with ExtensionIdProvider {
* if (Cluster(system).isLeader) { ... }
* }}}
*/
class Cluster(val system: ExtendedActorSystem, val failureDetector: FailureDetector) extends Extension with ClusterEnvironment {
class Cluster(val system: ExtendedActorSystem) extends Extension {
import ClusterEvent._
@ -88,6 +76,14 @@ class Cluster(val system: ExtendedActorSystem, val failureDetector: FailureDetec
log.info("Cluster Node [{}] - is starting up...", selfAddress)
val failureDetector = {
import settings.{ FailureDetectorImplementationClass fqcn }
system.dynamicAccess.createInstanceFor[FailureDetector](
fqcn, Seq(classOf[ActorSystem] -> system, classOf[ClusterSettings] -> settings)).fold(
e throw new ConfigurationException("Could not create custom failure detector [" + fqcn + "] due to:" + e.toString),
identity)
}
// ========================================================
// ===================== WORK DAEMONS =====================
// ========================================================
@ -142,16 +138,14 @@ class Cluster(val system: ExtendedActorSystem, val failureDetector: FailureDetec
// create supervisor for daemons under path "/system/cluster"
private val clusterDaemons: ActorRef = {
system.asInstanceOf[ActorSystemImpl].systemActorOf(Props(new ClusterDaemon(this)).
system.asInstanceOf[ActorSystemImpl].systemActorOf(Props[ClusterDaemon].
withDispatcher(UseDispatcher), name = "cluster")
}
/**
* INTERNAL API
*/
private[cluster] lazy val clusterCore: ActorRef = {
// this val must be lazy for correct initialization order,
// ClusterDaemon children may use for example subscribe before we get the GetClusterCoreRef reply
private[cluster] val clusterCore: ActorRef = {
implicit val timeout = system.settings.CreationTimeout
Await.result((clusterDaemons ? InternalClusterAction.GetClusterCoreRef).mapTo[ActorRef], timeout.duration)
}
@ -219,10 +213,12 @@ class Cluster(val system: ExtendedActorSystem, val failureDetector: FailureDetec
// ========================================================
/**
* Make it possible to override/configure seedNodes from tests without
* specifying in config. Addresses are unknown before startup time.
* Make it possible to join the specified seed nodes without defining them
* in config. Especially useful from tests when Addresses are unknown
* before startup time.
*/
private[cluster] def seedNodes: IndexedSeq[Address] = SeedNodes
private[cluster] def joinSeedNodes(seedNodes: IndexedSeq[Address]): Unit =
clusterCore ! InternalClusterAction.JoinSeedNodes(seedNodes)
/**
* INTERNAL API.