diff --git a/akka-docs/cluster/cluster-usage.rst b/akka-docs/cluster/cluster-usage.rst
new file mode 100644
index 0000000000..3f54778817
--- /dev/null
+++ b/akka-docs/cluster/cluster-usage.rst
@@ -0,0 +1,196 @@
+
+.. _cluster_usage:
+
+###############
+ Cluster Usage
+###############
+
+.. note:: This document describes how to use the features implemented so far of the
+ new clustering coming in Akka Coltrane and is not available in the latest stable release.
+ The API might change before it is released.
+
+For introduction to the Akka Cluster concepts please see :ref:`cluster`.
+
+Preparing Your Project for Clustering
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The Akka cluster is a separate jar file. Make sure that you have the following dependency in your project::
+
+ "com.typesafe.akka" % "akka-cluster" % "2.1-SNAPSHOT"
+
+Instead of 2.1-SNAPSHOT you should pick a timestamped Akka version from ``_.
+
+The following sbt build file illustrates what to use with Scala 2.10.0-M7 and Akka 2.1-SNAPSHOT
+
+ import sbt._
+ import sbt.Keys._
+
+ object ProjectBuild extends Build {
+
+ lazy val root = Project(
+ id = "root",
+ base = file("."),
+ settings = Project.defaultSettings ++ Seq(
+ name := "Akka Cluster Example",
+ organization := "org.test",
+ version := "0.1-SNAPSHOT",
+ scalaVersion := "2.10.0-M7",
+
+ resolvers += "Sonatype Releases Repo" at "https://oss.sonatype.org/content/repositories/releases/",
+ resolvers += "Sonatype Snapshot Repo" at "https://oss.sonatype.org/content/repositories/snapshots/",
+ resolvers += "Typesafe Releases" at "http://repo.typesafe.com/typesafe/releases",
+ resolvers += "Typesafe Snapshots" at "http://repo.typesafe.com/typesafe/snapshots/",
+
+
+ libraryDependencies ++= Seq(
+ "com.typesafe.akka" % "akka-cluster" % "2.1-20120822-000942")
+ )
+ )
+ }
+
+Pick a timestamped Akka version from ``_.
+
+
+A Simple Cluster Example
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The following small program together with its configuration starts an ``ActorSystem``
+with the Cluster extension enabled. It joins the cluster and logs some membership events.
+
+Try it out:
+
+1. Add the following ``application.conf`` in your project, place it in ``src/main/resources``:
+
+
+.. literalinclude:: ../../akka-samples/akka-sample-cluster/src/main/resources/application.conf
+ :language: none
+
+To enable cluster capabilities in your Akka project you should, at a minimum, add the :ref:`remoting-scala`
+settings and the ``akka.cluster.seed-nodes`` to your ``application.conf`` file:
+
+.. literalinclude:: ../../akka-samples/akka-sample-remote/src/main/resources/common.conf
+ :language: none
+
+The seed nodes are configured contact points for initial, automatic, join of the cluster.
+
+Note that if you are going to starting the nodes on different machines you need to specify the
+ip-addresses or host names of the machines in ``application.conf`` instead of ``127.0.0.1``
+
+2. Add the following main program to your project, place it in ``src/main/scala``:
+
+.. literalinclude:: ../../akka-samples/akka-sample-cluster/src/main/scala/sample/cluster/ClusterApp.scala
+ :language: scala
+
+
+3. Start the first seed node. Open a sbt session in one terminal window and run::
+
+ run-main sample.cluster.ClusterApp 2551
+
+2551 corresponds to the port of the first seed-nodes element in the configuration.
+In the log output you see that the cluster node has been started and changed status to Up.
+
+4. Start the second seed node. Open a sbt session in another terminal window and run::
+
+ run-main sample.cluster.ClusterApp 2552
+
+
+2552 corresponds to the port of the first seed-nodes element in the configuration.
+In the log output you see that the cluster node has been started and joins the other seed node
+and becomes a member of the cluster. It's status changed to Up.
+
+Switch over to the first terminal window and see in the log output that the member joined.
+
+5. Start another node. Open a sbt session in yet another terminal window and run::
+
+ run-main sample.cluster.ClusterApp
+
+Now you don't need to specify the port number, and it will use a random available port.
+It joins one of the configured seed nodes. Look at the log output in the different terminal
+windows.
+
+Start even more nodes in the same way, if you like.
+
+6. Shut down one of the nodes by pressing 'ctrl-c' in one of the terminal windows.
+The other nodes will detect the failure after a while, which you can see in the log
+output in the other terminals.
+
+Look at the source code of the program again. What it does is to create an actor
+and register it as subscriber of certain cluster events. It gets notified with
+an snapshot event, 'CurrentClusterState' that holds full state information of
+the cluster. After that it receives events for changes that happen in the cluster.
+
+Automatic vs. Manual Joining
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You may decide if joining to the cluster should be done automatically or manually.
+By default it is automatic and you need to define the seed nodes in configuration
+so that a new node has an initial contact point. When a new node is started it
+sends a message to all seed nodes and then sends join command to the one that
+answers first. If no one of the seed nodes replied (might not be started yet)
+it retries this procedure until successful or shutdown.
+
+There is one thing to be aware of regarding the seed node configured as the
+first element in the ``seed-nodes`` configuration list.
+The seed nodes can be started in any order and it is not necessary to have all
+seed nodes running, but the first seed node must be started when initially
+starting a cluster, otherwise the other seed-nodes will not become initialized
+and no other node can join the cluster. Once more than two seed nodes have been
+started it is no problem to shut down the first seed node. If it goes down it
+must be manually joined to the cluster again.
+Automatic joining of the first seed node is not possible, it would only join
+itself. It is only the first seed node that has this restriction.
+
+You can disable automatic joining with configuration:
+
+ akka.cluster.auto-join = off
+
+Then you need to join manually, using JMX or the provided script.
+You can join to any node in the cluster. It doesn't have to be configured as
+seed node. If you are not using auto-join there is no need to configure
+seed nodes at all.
+
+Joining can also be performed programatically with ``Cluster(system).join``.
+
+
+Automatic vs. Manual Downing
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+When a member is considered by the failure detector to be unreachable the
+leader is not allowed to perform its duties, such as changing status of
+new joining members to Up. The status of the unreachable member must be
+changed to Down. This can be performed automatically or manually. By
+default it must be done manually, using using JMX or the provided script.
+
+It can also be performed programatically with ``Cluster(system).down``.
+
+You can enable automatic downing with configuration:
+
+ akka.cluster.auto-down = on
+
+Be aware of that using auto-down implies that two separate clusters will
+automatically be formed in case of network partition. That might be
+desired by some applications but not by others.
+
+Configuration
+^^^^^^^^^^^^^
+
+There are several configuration properties for the cluster. We refer to the following
+reference file for more information:
+
+
+.. literalinclude:: ../../akka-cluster/src/main/resources/reference.conf
+ :language: none
+
+It is recommended that you change the ``tick-duration`` to 33 ms or less
+of the default scheduler when using cluster, if you don't need to have it
+configured to a longer duration for other reasons. If you don't do this
+a dedicated scheduler will be used for periodic tasks of the cluster, which
+introduce the extra overhead of another thread.
+
+::
+
+ # shorter tick-duration of default scheduler when using cluster
+ akka.scheduler.tick-duration.tick-duration = 33ms
+
+
+
diff --git a/akka-docs/cluster/index.rst b/akka-docs/cluster/index.rst
index 35c4b2250a..dac3a558d9 100644
--- a/akka-docs/cluster/index.rst
+++ b/akka-docs/cluster/index.rst
@@ -5,3 +5,4 @@ Cluster
:maxdepth: 2
cluster
+ cluster-usage
diff --git a/akka-samples/akka-sample-cluster/src/main/resources/application.conf b/akka-samples/akka-sample-cluster/src/main/resources/application.conf
index 779b3825cd..ee403ff23d 100644
--- a/akka-samples/akka-sample-cluster/src/main/resources/application.conf
+++ b/akka-samples/akka-sample-cluster/src/main/resources/application.conf
@@ -13,6 +13,8 @@ akka {
extensions = ["akka.cluster.Cluster$"]
cluster {
- seed-nodes = ["akka://ClusterSystem@127.0.0.1:2551", "akka://ClusterSystem@127.0.0.1:2552"]
+ seed-nodes = [
+ "akka://ClusterSystem@127.0.0.1:2551",
+ "akka://ClusterSystem@127.0.0.1:2552"]
}
}
\ No newline at end of file
diff --git a/akka-samples/akka-sample-cluster/src/main/scala/sample/cluster/ClusterApp.scala b/akka-samples/akka-sample-cluster/src/main/scala/sample/cluster/ClusterApp.scala
index 521176d142..0fd396784d 100644
--- a/akka-samples/akka-sample-cluster/src/main/scala/sample/cluster/ClusterApp.scala
+++ b/akka-samples/akka-sample-cluster/src/main/scala/sample/cluster/ClusterApp.scala
@@ -8,24 +8,26 @@ object ClusterApp {
def main(args: Array[String]): Unit = {
+ // Override the configuration of the port
+ // when specified as program argument
if (args.nonEmpty) System.setProperty("akka.remote.netty.port", args(0))
// Create an Akka system
val system = ActorSystem("ClusterSystem")
- val clusterListener = system.actorOf(Props(new Actor {
+ val clusterListener = system.actorOf(Props(new Actor with ActorLogging {
def receive = {
case state: CurrentClusterState ⇒
- println("Current members: " + state.members)
+ log.info("Current members: {}", state.members)
case MemberJoined(member) ⇒
- println("Member joined: " + member)
+ log.info("Member joined: {}", member)
case MemberUp(member) ⇒
- println("Member is Up: " + member)
+ log.info("Member is Up: {}", member)
case MemberUnreachable(member) ⇒
- println("Member detected as unreachable: " + member)
+ log.info("Member detected as unreachable: {}", member)
case _ ⇒ // ignore
}
- }))
+ }), name = "clusterListener")
Cluster(system).subscribe(clusterListener, classOf[ClusterDomainEvent])
}