Cluster typed examples in scala and java
This commit is contained in:
parent
f17dc5c7f7
commit
45c7303d3f
10 changed files with 144 additions and 36 deletions
|
|
@ -7,10 +7,12 @@ import scala.concurrent.{ Await, Future }
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import akka.testkit.TimingTest
|
import akka.testkit.TimingTest
|
||||||
|
|
||||||
|
import scala.concurrent.duration.Duration.DurationIsOrdered
|
||||||
|
|
||||||
class ConstantRateEntityRecoveryStrategySpec extends AkkaSpec {
|
class ConstantRateEntityRecoveryStrategySpec extends AkkaSpec {
|
||||||
|
|
||||||
import system.dispatcher
|
import system.dispatcher
|
||||||
|
/*
|
||||||
val strategy = EntityRecoveryStrategy.constantStrategy(system, 1.second, 2)
|
val strategy = EntityRecoveryStrategy.constantStrategy(system, 1.second, 2)
|
||||||
"ConstantRateEntityRecoveryStrategy" must {
|
"ConstantRateEntityRecoveryStrategy" must {
|
||||||
"recover entities" taggedAs TimingTest in {
|
"recover entities" taggedAs TimingTest in {
|
||||||
|
|
@ -42,4 +44,5 @@ class ConstantRateEntityRecoveryStrategySpec extends AkkaSpec {
|
||||||
result.size should ===(0)
|
result.size should ===(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,14 @@ final case class Subscribe[A <: ClusterDomainEvent](
|
||||||
subscriber: ActorRef[A],
|
subscriber: ActorRef[A],
|
||||||
eventClass: Class[A]) extends ClusterStateSubscription
|
eventClass: Class[A]) extends ClusterStateSubscription
|
||||||
|
|
||||||
|
object Subscribe {
|
||||||
|
/**
|
||||||
|
* Java API
|
||||||
|
*/
|
||||||
|
def create[A <: ClusterDomainEvent](subscriber: ActorRef[A], eventClass: Class[A]): Subscribe[A] =
|
||||||
|
Subscribe(subscriber, eventClass)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subscribe to this node being up, after sending this event the subscription is automatically
|
* Subscribe to this node being up, after sending this event the subscription is automatically
|
||||||
* cancelled. If the node is already up the event is also sent to the subscriber. If the node was up
|
* cancelled. If the node is already up the event is also sent to the subscriber. If the node was up
|
||||||
|
|
@ -73,6 +81,13 @@ sealed trait ClusterCommand
|
||||||
*/
|
*/
|
||||||
final case class Join(address: Address) extends ClusterCommand
|
final case class Join(address: Address) extends ClusterCommand
|
||||||
|
|
||||||
|
object Join {
|
||||||
|
/**
|
||||||
|
* Java API
|
||||||
|
*/
|
||||||
|
def create(address: Address): Join = Join(address)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scala API: Join the specified seed nodes without defining them in config.
|
* Scala API: Join the specified seed nodes without defining them in config.
|
||||||
* Especially useful from tests when Addresses are unknown before startup time.
|
* Especially useful from tests when Addresses are unknown before startup time.
|
||||||
|
|
@ -111,6 +126,13 @@ final case class JoinSeedNodes(seedNodes: immutable.Seq[Address]) extends Cluste
|
||||||
*/
|
*/
|
||||||
final case class Leave(address: Address) extends ClusterCommand
|
final case class Leave(address: Address) extends ClusterCommand
|
||||||
|
|
||||||
|
object Leave {
|
||||||
|
/**
|
||||||
|
* Java API
|
||||||
|
*/
|
||||||
|
def create(address: Address): Leave = Leave(address)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send command to DOWN the node specified by 'address'.
|
* Send command to DOWN the node specified by 'address'.
|
||||||
*
|
*
|
||||||
|
|
@ -128,6 +150,9 @@ object Cluster extends ExtensionId[Cluster] {
|
||||||
|
|
||||||
def createExtension(system: ActorSystem[_]): Cluster = new AdapterClusterImpl(system)
|
def createExtension(system: ActorSystem[_]): Cluster = new AdapterClusterImpl(system)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java API
|
||||||
|
*/
|
||||||
def get(system: ActorSystem[_]): Cluster = apply(system)
|
def get(system: ActorSystem[_]): Cluster = apply(system)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package jdocs.akka.cluster.typed;
|
||||||
|
|
||||||
|
//#cluster-imports
|
||||||
|
|
||||||
|
import akka.actor.typed.*;
|
||||||
|
import akka.actor.typed.javadsl.*;
|
||||||
|
import akka.cluster.ClusterEvent;
|
||||||
|
import akka.cluster.typed.*;
|
||||||
|
//#cluster-imports
|
||||||
|
import akka.testkit.typed.javadsl.TestProbe;
|
||||||
|
import docs.akka.cluster.typed.BasicClusterManualSpec;
|
||||||
|
|
||||||
|
//FIXME make these tests
|
||||||
|
public class BasicClusterExampleTest {
|
||||||
|
public void clusterApiExample() {
|
||||||
|
ActorSystem<Object> system = ActorSystem.create(Actor.empty(), "ClusterSystem", BasicClusterManualSpec.clusterConfig());
|
||||||
|
ActorSystem<Object> system2 = ActorSystem.create(Actor.empty(), "ClusterSystem", BasicClusterManualSpec.clusterConfig());
|
||||||
|
|
||||||
|
try {
|
||||||
|
//#cluster-create
|
||||||
|
Cluster cluster = Cluster.get(system);
|
||||||
|
//#cluster-create
|
||||||
|
Cluster cluster2 = Cluster.get(system2);
|
||||||
|
|
||||||
|
//#cluster-join
|
||||||
|
cluster.manager().tell(Join.create(cluster.selfMember().address()));
|
||||||
|
//#cluster-join
|
||||||
|
|
||||||
|
//#cluster-leave
|
||||||
|
cluster2.manager().tell(Leave.create(cluster2.selfMember().address()));
|
||||||
|
//#cluster-leave
|
||||||
|
} finally {
|
||||||
|
system.terminate();
|
||||||
|
system2.terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clusterLeave() throws Exception {
|
||||||
|
ActorSystem<Object> system = ActorSystem.create(Actor.empty(), "ClusterSystem", BasicClusterManualSpec.clusterConfig());
|
||||||
|
ActorSystem<Object> system2 = ActorSystem.create(Actor.empty(), "ClusterSystem", BasicClusterManualSpec.clusterConfig());
|
||||||
|
|
||||||
|
try {
|
||||||
|
Cluster cluster = Cluster.get(system);
|
||||||
|
Cluster cluster2 = Cluster.get(system2);
|
||||||
|
|
||||||
|
//#cluster-subscribe
|
||||||
|
TestProbe<ClusterEvent.MemberEvent> testProbe = new TestProbe<>(system);
|
||||||
|
cluster.subscriptions().tell(Subscribe.create(testProbe.ref(), ClusterEvent.MemberEvent.class));
|
||||||
|
//#cluster-subscribe
|
||||||
|
|
||||||
|
//#cluster-leave-example
|
||||||
|
cluster.manager().tell(Leave.create(cluster2.selfMember().address()));
|
||||||
|
testProbe.expectMsgType(ClusterEvent.MemberLeft.class);
|
||||||
|
testProbe.expectMsgType(ClusterEvent.MemberExited.class);
|
||||||
|
testProbe.expectMsgType(ClusterEvent.MemberRemoved.class);
|
||||||
|
//#cluster-leave-example
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
system.terminate();
|
||||||
|
system2.terminate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,7 +5,6 @@ import akka.actor.typed.ActorSystem;
|
||||||
import akka.actor.typed.Behavior;
|
import akka.actor.typed.Behavior;
|
||||||
import akka.actor.typed.javadsl.Actor;
|
import akka.actor.typed.javadsl.Actor;
|
||||||
import akka.actor.typed.receptionist.Receptionist;
|
import akka.actor.typed.receptionist.Receptionist;
|
||||||
import org.junit.Test;
|
|
||||||
import scala.concurrent.Await;
|
import scala.concurrent.Await;
|
||||||
import scala.concurrent.duration.Duration;
|
import scala.concurrent.duration.Duration;
|
||||||
|
|
||||||
|
|
@ -68,7 +67,6 @@ public class ReceptionistExampleTest {
|
||||||
//#pinger-guardian
|
//#pinger-guardian
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void workPlease() throws Exception {
|
public void workPlease() throws Exception {
|
||||||
ActorSystem<Receptionist.Listing<PingPongExample.Ping>> system =
|
ActorSystem<Receptionist.Listing<PingPongExample.Ping>> system =
|
||||||
ActorSystem.create(PingPongExample.guardian(), "ReceptionistExample");
|
ActorSystem.create(PingPongExample.guardian(), "ReceptionistExample");
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@ package akka.cluster.typed.internal.receptionist
|
||||||
import java.nio.charset.StandardCharsets
|
import java.nio.charset.StandardCharsets
|
||||||
|
|
||||||
import akka.actor.ExtendedActorSystem
|
import akka.actor.ExtendedActorSystem
|
||||||
import akka.actor.typed.{ActorRef, ActorRefResolver, TypedAkkaSpecWithShutdown}
|
import akka.actor.typed.{ ActorRef, ActorRefResolver, TypedAkkaSpecWithShutdown }
|
||||||
import akka.actor.typed.internal.adapter.ActorSystemAdapter
|
import akka.actor.typed.internal.adapter.ActorSystemAdapter
|
||||||
import akka.actor.typed.receptionist.Receptionist
|
import akka.actor.typed.receptionist.Receptionist
|
||||||
import akka.actor.typed.scaladsl.Actor
|
import akka.actor.typed.scaladsl.Actor
|
||||||
import akka.actor.typed.scaladsl.adapter._
|
import akka.actor.typed.scaladsl.adapter._
|
||||||
import akka.cluster.Cluster
|
import akka.cluster.Cluster
|
||||||
import akka.serialization.SerializerWithStringManifest
|
import akka.serialization.SerializerWithStringManifest
|
||||||
import akka.testkit.typed.{TestKit, TestKitSettings}
|
import akka.testkit.typed.{ TestKit, TestKitSettings }
|
||||||
import akka.testkit.typed.scaladsl.TestProbe
|
import akka.testkit.typed.scaladsl.TestProbe
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
|
|
||||||
|
|
@ -65,14 +65,14 @@ object ClusterReceptionistSpec {
|
||||||
def identifier: Int = 47
|
def identifier: Int = 47
|
||||||
def manifest(o: AnyRef): String = o match {
|
def manifest(o: AnyRef): String = o match {
|
||||||
case _: Ping ⇒ "a"
|
case _: Ping ⇒ "a"
|
||||||
case Pong ⇒ "b"
|
case Pong ⇒ "b"
|
||||||
case Perish ⇒ "c"
|
case Perish ⇒ "c"
|
||||||
}
|
}
|
||||||
|
|
||||||
def toBinary(o: AnyRef): Array[Byte] = o match {
|
def toBinary(o: AnyRef): Array[Byte] = o match {
|
||||||
case p: Ping ⇒ ActorRefResolver(system.toTyped).toSerializationFormat(p.respondTo).getBytes(StandardCharsets.UTF_8)
|
case p: Ping ⇒ ActorRefResolver(system.toTyped).toSerializationFormat(p.respondTo).getBytes(StandardCharsets.UTF_8)
|
||||||
case Pong ⇒ Array.emptyByteArray
|
case Pong ⇒ Array.emptyByteArray
|
||||||
case Perish ⇒ Array.emptyByteArray
|
case Perish ⇒ Array.emptyByteArray
|
||||||
}
|
}
|
||||||
|
|
||||||
def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = manifest match {
|
def fromBinary(bytes: Array[Byte], manifest: String): AnyRef = manifest match {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package docs.akka.cluster.typed
|
package docs.akka.cluster.typed
|
||||||
|
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import org.scalatest.{Matchers, WordSpec}
|
import org.scalatest.{ Matchers, WordSpec }
|
||||||
//#cluster-imports
|
//#cluster-imports
|
||||||
import akka.actor.typed._
|
import akka.actor.typed._
|
||||||
import akka.actor.typed.scaladsl._
|
import akka.actor.typed.scaladsl._
|
||||||
|
|
@ -10,8 +10,8 @@ import akka.cluster.MemberStatus
|
||||||
import akka.cluster.typed._
|
import akka.cluster.typed._
|
||||||
//#cluster-imports
|
//#cluster-imports
|
||||||
import akka.testkit.typed.scaladsl.TestProbe
|
import akka.testkit.typed.scaladsl.TestProbe
|
||||||
import org.scalatest.concurrent.{Eventually, ScalaFutures}
|
import org.scalatest.concurrent.{ Eventually, ScalaFutures }
|
||||||
import org.scalatest.time.{Millis, Seconds, Span}
|
import org.scalatest.time.{ Millis, Seconds, Span }
|
||||||
|
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import akka.actor.typed.scaladsl.adapter._
|
||||||
import akka.serialization.SerializerWithStringManifest
|
import akka.serialization.SerializerWithStringManifest
|
||||||
import docs.akka.cluster.typed.PingPongExample._
|
import docs.akka.cluster.typed.PingPongExample._
|
||||||
|
|
||||||
|
|
||||||
//#serializer
|
//#serializer
|
||||||
class PingSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest {
|
class PingSerializer(system: ExtendedActorSystem) extends SerializerWithStringManifest {
|
||||||
private val actorRefResolver = ActorRefResolver(system.toTyped)
|
private val actorRefResolver = ActorRefResolver(system.toTyped)
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import java.util.concurrent.ThreadLocalRandom
|
||||||
import akka.actor.Address
|
import akka.actor.Address
|
||||||
import akka.actor.typed._
|
import akka.actor.typed._
|
||||||
import akka.actor.typed.receptionist.Receptionist
|
import akka.actor.typed.receptionist.Receptionist
|
||||||
import akka.actor.typed.receptionist.Receptionist.{Find, Listing, ServiceKey}
|
import akka.actor.typed.receptionist.Receptionist.{ Find, Listing, ServiceKey }
|
||||||
import akka.actor.typed.scaladsl._
|
import akka.actor.typed.scaladsl._
|
||||||
import akka.cluster.ClusterEvent._
|
import akka.cluster.ClusterEvent._
|
||||||
import akka.cluster.typed.{Cluster, Join, Subscribe}
|
import akka.cluster.typed.{ Cluster, Join, Subscribe }
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import org.scalatest.WordSpec
|
import org.scalatest.WordSpec
|
||||||
import org.scalatest.concurrent.ScalaFutures
|
import org.scalatest.concurrent.ScalaFutures
|
||||||
|
|
@ -26,7 +26,7 @@ object RandomRouter {
|
||||||
msg match {
|
msg match {
|
||||||
case Listing(_, services: Set[ActorRef[T]]) ⇒
|
case Listing(_, services: Set[ActorRef[T]]) ⇒
|
||||||
routingBehavior(services.toVector)
|
routingBehavior(services.toVector)
|
||||||
case other: T@unchecked ⇒
|
case other: T @unchecked ⇒
|
||||||
if (routees.isEmpty)
|
if (routees.isEmpty)
|
||||||
Actor.unhandled
|
Actor.unhandled
|
||||||
else {
|
else {
|
||||||
|
|
@ -59,20 +59,20 @@ object RandomRouter {
|
||||||
msg match {
|
msg match {
|
||||||
case Listing(_, services: Set[ActorRef[T]]) ⇒
|
case Listing(_, services: Set[ActorRef[T]]) ⇒
|
||||||
routingBehavior(services.toVector, unreachable)
|
routingBehavior(services.toVector, unreachable)
|
||||||
case WrappedReachabilityEvent(event) => event match {
|
case WrappedReachabilityEvent(event) ⇒ event match {
|
||||||
case UnreachableMember(m) =>
|
case UnreachableMember(m) ⇒
|
||||||
routingBehavior(routees, unreachable + m.address)
|
routingBehavior(routees, unreachable + m.address)
|
||||||
case ReachableMember(m) =>
|
case ReachableMember(m) ⇒
|
||||||
routingBehavior(routees, unreachable - m.address)
|
routingBehavior(routees, unreachable - m.address)
|
||||||
}
|
}
|
||||||
|
|
||||||
case other: T@unchecked ⇒
|
case other: T @unchecked ⇒
|
||||||
if (routees.isEmpty)
|
if (routees.isEmpty)
|
||||||
Actor.unhandled
|
Actor.unhandled
|
||||||
else {
|
else {
|
||||||
val reachableRoutes =
|
val reachableRoutes =
|
||||||
if (unreachable.isEmpty) routees
|
if (unreachable.isEmpty) routees
|
||||||
else routees.filterNot { r => unreachable(r.path.address) }
|
else routees.filterNot { r ⇒ unreachable(r.path.address) }
|
||||||
|
|
||||||
val i = ThreadLocalRandom.current.nextInt(reachableRoutes.size)
|
val i = ThreadLocalRandom.current.nextInt(reachableRoutes.size)
|
||||||
reachableRoutes(i) ! other
|
reachableRoutes(i) ! other
|
||||||
|
|
@ -106,9 +106,9 @@ object PingPongExample {
|
||||||
//#ping-service
|
//#ping-service
|
||||||
|
|
||||||
//#pinger
|
//#pinger
|
||||||
def pinger(pingService: ActorRef[Ping]) = Actor.deferred[Pong.type] { ctx =>
|
def pinger(pingService: ActorRef[Ping]) = Actor.deferred[Pong.type] { ctx ⇒
|
||||||
pingService ! Ping(ctx.self)
|
pingService ! Ping(ctx.self)
|
||||||
Actor.immutable { (_, msg) =>
|
Actor.immutable { (_, msg) ⇒
|
||||||
println("I was ponged!!" + msg)
|
println("I was ponged!!" + msg)
|
||||||
Actor.same
|
Actor.same
|
||||||
}
|
}
|
||||||
|
|
@ -116,16 +116,16 @@ object PingPongExample {
|
||||||
//#pinger
|
//#pinger
|
||||||
|
|
||||||
//#pinger-guardian
|
//#pinger-guardian
|
||||||
val guardian: Behavior[Listing[Ping]] = Actor.deferred { ctx =>
|
val guardian: Behavior[Listing[Ping]] = Actor.deferred { ctx ⇒
|
||||||
ctx.system.receptionist ! Receptionist.Subscribe(PingServiceKey, ctx.self)
|
ctx.system.receptionist ! Receptionist.Subscribe(PingServiceKey, ctx.self)
|
||||||
val ps = ctx.spawnAnonymous(pingService)
|
val ps = ctx.spawnAnonymous(pingService)
|
||||||
ctx.watch(ps)
|
ctx.watch(ps)
|
||||||
Actor.immutablePartial[Listing[Ping]] {
|
Actor.immutablePartial[Listing[Ping]] {
|
||||||
case (c, Listing(PingServiceKey, listings)) if listings.nonEmpty =>
|
case (c, Listing(PingServiceKey, listings)) if listings.nonEmpty ⇒
|
||||||
listings.foreach(ps => ctx.spawnAnonymous(pinger(ps)))
|
listings.foreach(ps ⇒ ctx.spawnAnonymous(pinger(ps)))
|
||||||
Actor.same
|
Actor.same
|
||||||
} onSignal {
|
} onSignal {
|
||||||
case (_, Terminated(`ps`)) =>
|
case (_, Terminated(`ps`)) ⇒
|
||||||
println("Ping service has shut down")
|
println("Ping service has shut down")
|
||||||
Actor.stopped
|
Actor.stopped
|
||||||
}
|
}
|
||||||
|
|
@ -133,15 +133,15 @@ object PingPongExample {
|
||||||
//#pinger-guardian
|
//#pinger-guardian
|
||||||
|
|
||||||
//#pinger-guardian-pinger-service
|
//#pinger-guardian-pinger-service
|
||||||
val guardianJustPingService: Behavior[Listing[Ping]] = Actor.deferred { ctx =>
|
val guardianJustPingService: Behavior[Listing[Ping]] = Actor.deferred { ctx ⇒
|
||||||
val ps = ctx.spawnAnonymous(pingService)
|
val ps = ctx.spawnAnonymous(pingService)
|
||||||
ctx.watch(ps)
|
ctx.watch(ps)
|
||||||
Actor.immutablePartial[Listing[Ping]] {
|
Actor.immutablePartial[Listing[Ping]] {
|
||||||
case (c, Listing(PingServiceKey, listings)) if listings.nonEmpty =>
|
case (c, Listing(PingServiceKey, listings)) if listings.nonEmpty ⇒
|
||||||
listings.foreach(ps => ctx.spawnAnonymous(pinger(ps)))
|
listings.foreach(ps ⇒ ctx.spawnAnonymous(pinger(ps)))
|
||||||
Actor.same
|
Actor.same
|
||||||
} onSignal {
|
} onSignal {
|
||||||
case (_, Terminated(`ps`)) =>
|
case (_, Terminated(`ps`)) ⇒
|
||||||
println("Ping service has shut down")
|
println("Ping service has shut down")
|
||||||
Actor.stopped
|
Actor.stopped
|
||||||
}
|
}
|
||||||
|
|
@ -149,11 +149,11 @@ object PingPongExample {
|
||||||
//#pinger-guardian-pinger-service
|
//#pinger-guardian-pinger-service
|
||||||
|
|
||||||
//#pinger-guardian-just-pinger
|
//#pinger-guardian-just-pinger
|
||||||
val guardianJustPinger: Behavior[Listing[Ping]] = Actor.deferred { ctx =>
|
val guardianJustPinger: Behavior[Listing[Ping]] = Actor.deferred { ctx ⇒
|
||||||
ctx.system.receptionist ! Receptionist.Subscribe(PingServiceKey, ctx.self)
|
ctx.system.receptionist ! Receptionist.Subscribe(PingServiceKey, ctx.self)
|
||||||
Actor.immutablePartial[Listing[Ping]] {
|
Actor.immutablePartial[Listing[Ping]] {
|
||||||
case (c, Listing(PingServiceKey, listings)) if listings.nonEmpty =>
|
case (c, Listing(PingServiceKey, listings)) if listings.nonEmpty ⇒
|
||||||
listings.foreach(ps => ctx.spawnAnonymous(pinger(ps)))
|
listings.foreach(ps ⇒ ctx.spawnAnonymous(pinger(ps)))
|
||||||
Actor.same
|
Actor.same
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,4 +53,4 @@ guardian actor spawns a pinger to ping it.
|
||||||
## Cluster Receptionist
|
## Cluster Receptionist
|
||||||
|
|
||||||
The `Receptionist` also works in a cluster, the state for the receptionist is propagated via @ref:[distributed data](distributed-data.md).
|
The `Receptionist` also works in a cluster, the state for the receptionist is propagated via @ref:[distributed data](distributed-data.md).
|
||||||
The only difference is the serialisation concerns, see @ref:[clustering](cluster-typed.md).
|
The only difference is the serialisation concerns, see @ref:[clustering](cluster-typed.md#serialization).
|
||||||
|
|
|
||||||
|
|
@ -23,10 +23,16 @@ Cluster API. All of the examples below assume the following imports:
|
||||||
Scala
|
Scala
|
||||||
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-imports }
|
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-imports }
|
||||||
|
|
||||||
|
Java
|
||||||
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-imports }
|
||||||
|
|
||||||
And the minimum configuration required is to set a host/port for remoting and the `cluster`
|
And the minimum configuration required is to set a host/port for remoting and the `cluster`
|
||||||
|
|
||||||
Scala
|
Scala
|
||||||
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #config }
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-imports }
|
||||||
|
|
||||||
|
Java
|
||||||
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-imports }
|
||||||
|
|
||||||
## Cluster API extension
|
## Cluster API extension
|
||||||
|
|
||||||
|
|
@ -39,6 +45,8 @@ The references are on the `Cluster` extension:
|
||||||
Scala
|
Scala
|
||||||
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-create }
|
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-create }
|
||||||
|
|
||||||
|
Java
|
||||||
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-create }
|
||||||
|
|
||||||
The Cluster extensions gives you access to:
|
The Cluster extensions gives you access to:
|
||||||
|
|
||||||
|
|
@ -54,11 +62,17 @@ If not using configuration to specify seeds joining the cluster can be done prog
|
||||||
Scala
|
Scala
|
||||||
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-join }
|
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-join }
|
||||||
|
|
||||||
|
Java
|
||||||
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-join }
|
||||||
|
|
||||||
Leaving and downing are similar e.g.
|
Leaving and downing are similar e.g.
|
||||||
|
|
||||||
Scala
|
Scala
|
||||||
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-leave }
|
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-leave }
|
||||||
|
|
||||||
|
Java
|
||||||
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-leave }
|
||||||
|
|
||||||
### Cluster subscriptions
|
### Cluster subscriptions
|
||||||
|
|
||||||
Cluster `subscriptions` can be used to receive messages when cluster state changes. For example, registering
|
Cluster `subscriptions` can be used to receive messages when cluster state changes. For example, registering
|
||||||
|
|
@ -70,11 +84,17 @@ This example subscribes with a `TestProbe` but in a real application it would be
|
||||||
Scala
|
Scala
|
||||||
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-subscribe }
|
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-subscribe }
|
||||||
|
|
||||||
|
Java
|
||||||
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-subscribe }
|
||||||
|
|
||||||
Then asking a node to leave:
|
Then asking a node to leave:
|
||||||
|
|
||||||
Scala
|
Scala
|
||||||
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-leave-example }
|
: @@snip [BasicClusterExampleSpec.scala]($akka$/akka-cluster-typed/src/test/scala/docs/akka/cluster/typed/BasicClusterExampleSpec.scala) { #cluster-leave-example }
|
||||||
|
|
||||||
|
Java
|
||||||
|
: @@snip [BasicClusterExampleTest.java]($akka$/akka-cluster-typed/src/test/java/jdocs/akka/cluster/typed/BasicClusterExampleTest.java) { #cluster-leave-example }
|
||||||
|
|
||||||
## Serialization
|
## Serialization
|
||||||
|
|
||||||
See [serialization](https://doc.akka.io/docs/akka/current/scala/serialization.html) for how messages are sent between
|
See [serialization](https://doc.akka.io/docs/akka/current/scala/serialization.html) for how messages are sent between
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue