Formatting java codes with sbt-java-formatter.

This commit is contained in:
hepin1989 2019-01-12 04:00:53 +08:00
parent 27500001ea
commit 998c5a9285
401 changed files with 19750 additions and 17450 deletions

View file

@ -15,23 +15,24 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
//#join-seed-nodes-imports
// #join-seed-nodes-imports
import akka.actor.Address;
import akka.cluster.Cluster;
//#join-seed-nodes-imports
// #join-seed-nodes-imports
import akka.actor.ActorSystem;
import akka.cluster.Member;
public class ClusterDocTest extends AbstractJavaTest {
static ActorSystem system;
@BeforeClass
public static void setup() {
system = ActorSystem.create("ClusterDocTest",
ConfigFactory.parseString(scala.docs.cluster.ClusterDocSpec.config()));
system =
ActorSystem.create(
"ClusterDocTest",
ConfigFactory.parseString(scala.docs.cluster.ClusterDocSpec.config()));
}
@AfterClass
@ -42,17 +43,17 @@ public class ClusterDocTest extends AbstractJavaTest {
@Test
public void demonstrateLeave() {
//#leave
// #leave
final Cluster cluster = Cluster.get(system);
cluster.leave(cluster.selfAddress());
//#leave
// #leave
}
// compile only
// compile only
@SuppressWarnings("unused")
public void demonstrateDataCenter() {
//#dcAccess
// #dcAccess
final Cluster cluster = Cluster.get(system);
// this node's data center
String dc = cluster.selfDataCenter();
@ -61,16 +62,17 @@ public class ClusterDocTest extends AbstractJavaTest {
// a specific member's data center
Member aMember = cluster.state().getMembers().iterator().next();
String aDc = aMember.dataCenter();
//#dcAccess
// #dcAccess
}
// compile only
@SuppressWarnings("unused")
public void demonstrateJoinSeedNodes() {
//#join-seed-nodes
// #join-seed-nodes
final Cluster cluster = Cluster.get(system);
List<Address> list = new LinkedList<>(); //replace this with your method to dynamically get seed nodes
List<Address> list =
new LinkedList<>(); // replace this with your method to dynamically get seed nodes
cluster.joinSeedNodes(list);
//#join-seed-nodes
// #join-seed-nodes
}
}

View file

@ -10,22 +10,22 @@ import java.util.concurrent.CompletableFuture;
import akka.actor.AbstractActor;
import static akka.pattern.Patterns.pipe;
//#backend
// #backend
public class FactorialBackend extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(Integer.class, n -> {
.match(
Integer.class,
n -> {
CompletableFuture<FactorialResult> result =
CompletableFuture.supplyAsync(() -> factorial(n))
.thenApply((factorial) -> new FactorialResult(n, factorial));
CompletableFuture<FactorialResult> result =
CompletableFuture.supplyAsync(() -> factorial(n))
.thenApply((factorial) -> new FactorialResult(n, factorial));
pipe(result, getContext().dispatcher()).to(getSender());
})
.build();
pipe(result, getContext().dispatcher()).to(getSender());
})
.build();
}
BigInteger factorial(int n) {
@ -36,5 +36,4 @@ public class FactorialBackend extends AbstractActor {
return acc;
}
}
//#backend
// #backend

View file

@ -26,15 +26,15 @@ import akka.event.Logging;
import akka.event.LoggingAdapter;
import akka.routing.FromConfig;
//#frontend
// #frontend
public class FactorialFrontend extends AbstractActor {
final int upToN;
final boolean repeat;
LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
ActorRef backend = getContext().actorOf(FromConfig.getInstance().props(),
"factorialBackendRouter");
ActorRef backend =
getContext().actorOf(FromConfig.getInstance().props(), "factorialBackendRouter");
public FactorialFrontend(int upToN, boolean repeat) {
this.upToN = upToN;
@ -50,20 +50,22 @@ public class FactorialFrontend extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(FactorialResult.class, result -> {
if (result.n == upToN) {
log.debug("{}! = {}", result.n, result.factorial);
if (repeat)
sendJobs();
else
getContext().stop(getSelf());
}
})
.match(ReceiveTimeout.class, x -> {
log.info("Timeout");
sendJobs();
})
.build();
.match(
FactorialResult.class,
result -> {
if (result.n == upToN) {
log.debug("{}! = {}", result.n, result.factorial);
if (repeat) sendJobs();
else getContext().stop(getSelf());
}
})
.match(
ReceiveTimeout.class,
x -> {
log.info("Timeout");
sendJobs();
})
.build();
}
void sendJobs() {
@ -72,38 +74,46 @@ public class FactorialFrontend extends AbstractActor {
backend.tell(n, getSelf());
}
}
}
//#frontend
// #frontend
//not used, only for documentation
// not used, only for documentation
abstract class FactorialFrontend2 extends AbstractActor {
//#router-lookup-in-code
// #router-lookup-in-code
int totalInstances = 100;
Iterable<String> routeesPaths = Arrays.asList("/user/factorialBackend", "");
boolean allowLocalRoutees = true;
Set<String> useRoles = new HashSet<>(Arrays.asList("backend"));
ActorRef backend = getContext().actorOf(
new ClusterRouterGroup(new AdaptiveLoadBalancingGroup(
HeapMetricsSelector.getInstance(), Collections.<String> emptyList()),
new ClusterRouterGroupSettings(totalInstances, routeesPaths,
allowLocalRoutees, useRoles)).props(), "factorialBackendRouter2");
ActorRef backend =
getContext()
.actorOf(
new ClusterRouterGroup(
new AdaptiveLoadBalancingGroup(
HeapMetricsSelector.getInstance(), Collections.<String>emptyList()),
new ClusterRouterGroupSettings(
totalInstances, routeesPaths, allowLocalRoutees, useRoles))
.props(),
"factorialBackendRouter2");
//#router-lookup-in-code
// #router-lookup-in-code
}
//not used, only for documentation
// not used, only for documentation
abstract class FactorialFrontend3 extends AbstractActor {
//#router-deploy-in-code
// #router-deploy-in-code
int totalInstances = 100;
int maxInstancesPerNode = 3;
boolean allowLocalRoutees = false;
Set<String> useRoles = new HashSet<>(Arrays.asList("backend"));
ActorRef backend = getContext().actorOf(
new ClusterRouterPool(new AdaptiveLoadBalancingPool(
SystemLoadAverageMetricsSelector.getInstance(), 0),
new ClusterRouterPoolSettings(totalInstances, maxInstancesPerNode,
allowLocalRoutees, useRoles)).props(Props
.create(FactorialBackend.class)), "factorialBackendRouter3");
//#router-deploy-in-code
ActorRef backend =
getContext()
.actorOf(
new ClusterRouterPool(
new AdaptiveLoadBalancingPool(
SystemLoadAverageMetricsSelector.getInstance(), 0),
new ClusterRouterPoolSettings(
totalInstances, maxInstancesPerNode, allowLocalRoutees, useRoles))
.props(Props.create(FactorialBackend.class)),
"factorialBackendRouter3");
// #router-deploy-in-code
}

View file

@ -19,56 +19,60 @@ public class FactorialFrontendMain {
public static void main(String[] args) {
final int upToN = 200;
final Config config = ConfigFactory.parseString(
"akka.cluster.roles = [frontend]").withFallback(
ConfigFactory.load("factorial"));
final Config config =
ConfigFactory.parseString("akka.cluster.roles = [frontend]")
.withFallback(ConfigFactory.load("factorial"));
final ActorSystem system = ActorSystem.create("ClusterSystem", config);
system.log().info(
"Factorials will start when 2 backend members in the cluster.");
//#registerOnUp
Cluster.get(system).registerOnMemberUp(new Runnable() {
@Override
public void run() {
system.actorOf(Props.create(FactorialFrontend.class, upToN, true),
"factorialFrontend");
}
});
//#registerOnUp
system.log().info("Factorials will start when 2 backend members in the cluster.");
// #registerOnUp
Cluster.get(system)
.registerOnMemberUp(
new Runnable() {
@Override
public void run() {
system.actorOf(
Props.create(FactorialFrontend.class, upToN, true), "factorialFrontend");
}
});
// #registerOnUp
//#registerOnRemoved
Cluster.get(system).registerOnMemberRemoved(new Runnable() {
@Override
public void run() {
// exit JVM when ActorSystem has been terminated
final Runnable exit = new Runnable() {
@Override public void run() {
System.exit(0);
}
};
system.registerOnTermination(exit);
// #registerOnRemoved
Cluster.get(system)
.registerOnMemberRemoved(
new Runnable() {
@Override
public void run() {
// exit JVM when ActorSystem has been terminated
final Runnable exit =
new Runnable() {
@Override
public void run() {
System.exit(0);
}
};
system.registerOnTermination(exit);
// shut down ActorSystem
system.terminate();
// shut down ActorSystem
system.terminate();
// In case ActorSystem shutdown takes longer than 10 seconds,
// exit the JVM forcefully anyway.
// We must spawn a separate thread to not block current thread,
// since that would have blocked the shutdown of the ActorSystem.
new Thread() {
@Override public void run(){
try {
system.getWhenTerminated().toCompletableFuture().get(10, TimeUnit.SECONDS);
} catch (Exception e) {
System.exit(-1);
}
}
}.start();
}
});
//#registerOnRemoved
// In case ActorSystem shutdown takes longer than 10 seconds,
// exit the JVM forcefully anyway.
// We must spawn a separate thread to not block current thread,
// since that would have blocked the shutdown of the ActorSystem.
new Thread() {
@Override
public void run() {
try {
system.getWhenTerminated().toCompletableFuture().get(10, TimeUnit.SECONDS);
} catch (Exception e) {
System.exit(-1);
}
}
}.start();
}
});
// #registerOnRemoved
}
}

View file

@ -8,12 +8,12 @@ import java.math.BigInteger;
import java.io.Serializable;
public class FactorialResult implements Serializable {
private static final long serialVersionUID = 1L;
public final int n;
public final BigInteger factorial;
private static final long serialVersionUID = 1L;
public final int n;
public final BigInteger factorial;
FactorialResult(int n, BigInteger factorial) {
this.n = n;
this.factorial = factorial;
}
FactorialResult(int n, BigInteger factorial) {
this.n = n;
this.factorial = factorial;
}
}

View file

@ -4,7 +4,7 @@
package jdocs.cluster;
//#metrics-listener
// #metrics-listener
import akka.actor.AbstractActor;
import akka.cluster.Cluster;
import akka.cluster.ClusterEvent.CurrentClusterState;
@ -21,37 +21,40 @@ public class MetricsListener extends AbstractActor {
LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
Cluster cluster = Cluster.get(getContext().getSystem());
ClusterMetricsExtension extension = ClusterMetricsExtension.get(getContext().getSystem());
// Subscribe unto ClusterMetricsEvent events.
@Override
public void preStart() {
extension.subscribe(getSelf());
extension.subscribe(getSelf());
}
// Unsubscribe from ClusterMetricsEvent events.
@Override
public void postStop() {
extension.unsubscribe(getSelf());
extension.unsubscribe(getSelf());
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(ClusterMetricsChanged.class, clusterMetrics -> {
for (NodeMetrics nodeMetrics : clusterMetrics.getNodeMetrics()) {
if (nodeMetrics.address().equals(cluster.selfAddress())) {
logHeap(nodeMetrics);
logCpu(nodeMetrics);
}
}
})
.match(CurrentClusterState.class, message -> {
// Ignore.
})
.build();
.match(
ClusterMetricsChanged.class,
clusterMetrics -> {
for (NodeMetrics nodeMetrics : clusterMetrics.getNodeMetrics()) {
if (nodeMetrics.address().equals(cluster.selfAddress())) {
logHeap(nodeMetrics);
logCpu(nodeMetrics);
}
}
})
.match(
CurrentClusterState.class,
message -> {
// Ignore.
})
.build();
}
void logHeap(NodeMetrics nodeMetrics) {
@ -64,10 +67,8 @@ public class MetricsListener extends AbstractActor {
void logCpu(NodeMetrics nodeMetrics) {
Cpu cpu = StandardMetrics.extractCpu(nodeMetrics);
if (cpu != null && cpu.systemLoadAverage().isDefined()) {
log.info("Load: {} ({} processors)", cpu.systemLoadAverage().get(),
cpu.processors());
log.info("Load: {} ({} processors)", cpu.systemLoadAverage().get(), cpu.processors());
}
}
}
//#metrics-listener
// #metrics-listener

View file

@ -18,16 +18,16 @@ public class SimpleClusterListener extends AbstractActor {
LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
Cluster cluster = Cluster.get(getContext().getSystem());
//subscribe to cluster changes
// subscribe to cluster changes
@Override
public void preStart() {
//#subscribe
cluster.subscribe(getSelf(), ClusterEvent.initialStateAsEvents(),
MemberEvent.class, UnreachableMember.class);
//#subscribe
// #subscribe
cluster.subscribe(
getSelf(), ClusterEvent.initialStateAsEvents(), MemberEvent.class, UnreachableMember.class);
// #subscribe
}
//re-subscribe when restart
// re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
@ -36,18 +36,26 @@ public class SimpleClusterListener extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(MemberUp.class, mUp -> {
log.info("Member is Up: {}", mUp.member());
})
.match(UnreachableMember.class, mUnreachable -> {
log.info("Member detected as unreachable: {}", mUnreachable.member());
})
.match(MemberRemoved.class, mRemoved -> {
log.info("Member is Removed: {}", mRemoved.member());
})
.match(MemberEvent.class, message -> {
// ignore
})
.build();
.match(
MemberUp.class,
mUp -> {
log.info("Member is Up: {}", mUp.member());
})
.match(
UnreachableMember.class,
mUnreachable -> {
log.info("Member detected as unreachable: {}", mUnreachable.member());
})
.match(
MemberRemoved.class,
mRemoved -> {
log.info("Member is Removed: {}", mRemoved.member());
})
.match(
MemberEvent.class,
message -> {
// ignore
})
.build();
}
}

View file

@ -16,29 +16,28 @@ import akka.event.LoggingAdapter;
public class SimpleClusterListener2 extends AbstractActor {
LoggingAdapter log = Logging.getLogger(getContext().getSystem(), this);
//#join
// #join
Cluster cluster = Cluster.get(getContext().getSystem());
//#join
// #join
//subscribe to cluster changes
// subscribe to cluster changes
@Override
public void preStart() {
//#join
// #join
cluster.join(cluster.selfAddress());
//#join
// #join
//#subscribe
// #subscribe
cluster.subscribe(getSelf(), MemberEvent.class, UnreachableMember.class);
//#subscribe
// #subscribe
//#register-on-memberup
// #register-on-memberup
cluster.registerOnMemberUp(
() -> cluster.subscribe(getSelf(), MemberEvent.class, UnreachableMember.class)
);
//#register-on-memberup
() -> cluster.subscribe(getSelf(), MemberEvent.class, UnreachableMember.class));
// #register-on-memberup
}
//re-subscribe when restart
// re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
@ -47,21 +46,31 @@ public class SimpleClusterListener2 extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(CurrentClusterState.class, state -> {
log.info("Current members: {}", state.members());
})
.match(MemberUp.class, mUp -> {
log.info("Member is Up: {}", mUp.member());
})
.match(UnreachableMember.class, mUnreachable -> {
log.info("Member detected as unreachable: {}", mUnreachable.member());
})
.match(MemberRemoved.class, mRemoved -> {
log.info("Member is Removed: {}", mRemoved.member());
})
.match(MemberEvent.class, event -> {
// ignore
})
.build();
.match(
CurrentClusterState.class,
state -> {
log.info("Current members: {}", state.members());
})
.match(
MemberUp.class,
mUp -> {
log.info("Member is Up: {}", mUp.member());
})
.match(
UnreachableMember.class,
mUnreachable -> {
log.info("Member detected as unreachable: {}", mUnreachable.member());
})
.match(
MemberRemoved.class,
mRemoved -> {
log.info("Member is Removed: {}", mRemoved.member());
})
.match(
MemberEvent.class,
event -> {
// ignore
})
.build();
}
}

View file

@ -14,7 +14,7 @@ import akka.actor.ActorRef;
import akka.actor.ReceiveTimeout;
import akka.actor.AbstractActor;
//#aggregator
// #aggregator
public class StatsAggregator extends AbstractActor {
final int expectedResults;
@ -34,25 +34,27 @@ public class StatsAggregator extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(Integer.class, wordCount -> {
results.add(wordCount);
if (results.size() == expectedResults) {
int sum = 0;
for (int c : results) {
sum += c;
}
double meanWordLength = ((double) sum) / results.size();
replyTo.tell(new StatsResult(meanWordLength), getSelf());
getContext().stop(getSelf());
}
})
.match(ReceiveTimeout.class, x -> {
replyTo.tell(new JobFailed("Service unavailable, try again later"),
getSelf());
getContext().stop(getSelf());
})
.build();
.match(
Integer.class,
wordCount -> {
results.add(wordCount);
if (results.size() == expectedResults) {
int sum = 0;
for (int c : results) {
sum += c;
}
double meanWordLength = ((double) sum) / results.size();
replyTo.tell(new StatsResult(meanWordLength), getSelf());
getContext().stop(getSelf());
}
})
.match(
ReceiveTimeout.class,
x -> {
replyTo.tell(new JobFailed("Service unavailable, try again later"), getSelf());
getContext().stop(getSelf());
})
.build();
}
}
//#aggregator
// #aggregator

View file

@ -6,7 +6,7 @@ package jdocs.cluster;
import java.io.Serializable;
//#messages
// #messages
public interface StatsMessages {
public static class StatsJob implements Serializable {
@ -54,6 +54,5 @@ public interface StatsMessages {
return "JobFailed(" + reason + ")";
}
}
}
//#messages
// #messages

View file

@ -39,20 +39,20 @@ public class StatsSampleClient extends AbstractActor {
public StatsSampleClient(String servicePath) {
this.servicePath = servicePath;
Duration interval = Duration.ofMillis(2);
tickTask = getContext()
.getSystem()
.scheduler()
.schedule(interval, interval, getSelf(), "tick",
getContext().getDispatcher(), null);
tickTask =
getContext()
.getSystem()
.scheduler()
.schedule(interval, interval, getSelf(), "tick", getContext().getDispatcher(), null);
}
//subscribe to cluster changes, MemberEvent
// subscribe to cluster changes, MemberEvent
@Override
public void preStart() {
cluster.subscribe(getSelf(), MemberEvent.class, ReachabilityEvent.class);
}
//re-subscribe when restart
// re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
@ -62,41 +62,49 @@ public class StatsSampleClient extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.matchEquals("tick", x -> !nodes.isEmpty(), x -> {
// just pick any one
List<Address> nodesList = new ArrayList<Address>(nodes);
Address address = nodesList.get(ThreadLocalRandom.current().nextInt(
nodesList.size()));
ActorSelection service = getContext().actorSelection(address + servicePath);
service.tell(new StatsJob("this is the text that will be analyzed"),
getSelf());
})
.match(StatsResult.class, System.out::println)
.match(JobFailed.class, System.out::println)
.match(CurrentClusterState.class, state -> {
nodes.clear();
for (Member member : state.getMembers()) {
if (member.hasRole("compute") && member.status().equals(MemberStatus.up())) {
nodes.add(member.address());
}
}
})
.match(MemberUp.class, mUp -> {
if (mUp.member().hasRole("compute"))
nodes.add(mUp.member().address());
})
.match(MemberEvent.class, event -> {
nodes.remove(event.member().address());
})
.match(UnreachableMember.class, unreachable -> {
nodes.remove(unreachable.member().address());
})
.match(ReachableMember.class, reachable -> {
if (reachable.member().hasRole("compute"))
nodes.add(reachable.member().address());
})
.build();
.matchEquals(
"tick",
x -> !nodes.isEmpty(),
x -> {
// just pick any one
List<Address> nodesList = new ArrayList<Address>(nodes);
Address address =
nodesList.get(ThreadLocalRandom.current().nextInt(nodesList.size()));
ActorSelection service = getContext().actorSelection(address + servicePath);
service.tell(new StatsJob("this is the text that will be analyzed"), getSelf());
})
.match(StatsResult.class, System.out::println)
.match(JobFailed.class, System.out::println)
.match(
CurrentClusterState.class,
state -> {
nodes.clear();
for (Member member : state.getMembers()) {
if (member.hasRole("compute") && member.status().equals(MemberStatus.up())) {
nodes.add(member.address());
}
}
})
.match(
MemberUp.class,
mUp -> {
if (mUp.member().hasRole("compute")) nodes.add(mUp.member().address());
})
.match(
MemberEvent.class,
event -> {
nodes.remove(event.member().address());
})
.match(
UnreachableMember.class,
unreachable -> {
nodes.remove(unreachable.member().address());
})
.match(
ReachableMember.class,
reachable -> {
if (reachable.member().hasRole("compute")) nodes.add(reachable.member().address());
})
.build();
}
}

View file

@ -13,11 +13,7 @@ public class StatsSampleOneMasterClientMain {
public static void main(String[] args) {
// note that client is not a compute node, role not defined
ActorSystem system = ActorSystem.create("ClusterSystem",
ConfigFactory.load("stats2"));
system.actorOf(Props.create(StatsSampleClient.class, "/user/statsServiceProxy"),
"client");
ActorSystem system = ActorSystem.create("ClusterSystem", ConfigFactory.load("stats2"));
system.actorOf(Props.create(StatsSampleClient.class, "/user/statsServiceProxy"), "client");
}
}

View file

@ -19,7 +19,7 @@ public class StatsSampleOneMasterMain {
public static void main(String[] args) {
if (args.length == 0) {
startup(new String[] { "2551", "2552", "0" });
startup(new String[] {"2551", "2552", "0"});
StatsSampleOneMasterClientMain.main(new String[0]);
} else {
startup(args);
@ -29,29 +29,28 @@ public class StatsSampleOneMasterMain {
public static void startup(String[] ports) {
for (String port : ports) {
// Override the configuration of the port
Config config = ConfigFactory
.parseString("akka.remote.netty.tcp.port=" + port)
.withFallback(
ConfigFactory.parseString("akka.cluster.roles = [compute]"))
.withFallback(ConfigFactory.load("stats2"));
Config config =
ConfigFactory.parseString("akka.remote.netty.tcp.port=" + port)
.withFallback(ConfigFactory.parseString("akka.cluster.roles = [compute]"))
.withFallback(ConfigFactory.load("stats2"));
ActorSystem system = ActorSystem.create("ClusterSystem", config);
//#create-singleton-manager
ClusterSingletonManagerSettings settings = ClusterSingletonManagerSettings.create(system)
.withRole("compute");
system.actorOf(ClusterSingletonManager.props(
Props.create(StatsService.class), PoisonPill.getInstance(), settings),
// #create-singleton-manager
ClusterSingletonManagerSettings settings =
ClusterSingletonManagerSettings.create(system).withRole("compute");
system.actorOf(
ClusterSingletonManager.props(
Props.create(StatsService.class), PoisonPill.getInstance(), settings),
"statsService");
//#create-singleton-manager
// #create-singleton-manager
//#singleton-proxy
// #singleton-proxy
ClusterSingletonProxySettings proxySettings =
ClusterSingletonProxySettings.create(system).withRole("compute");
system.actorOf(ClusterSingletonProxy.props("/user/statsService",
proxySettings), "statsServiceProxy");
//#singleton-proxy
system.actorOf(
ClusterSingletonProxy.props("/user/statsService", proxySettings), "statsServiceProxy");
// #singleton-proxy
}
}
}

View file

@ -22,66 +22,74 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
//#service
// #service
public class StatsService extends AbstractActor {
// This router is used both with lookup and deploy of routees. If you
// have a router with only lookup of routees you can use Props.empty()
// instead of Props.create(StatsWorker.class).
ActorRef workerRouter = getContext().actorOf(
FromConfig.getInstance().props(Props.create(StatsWorker.class)),
"workerRouter");
ActorRef workerRouter =
getContext()
.actorOf(FromConfig.getInstance().props(Props.create(StatsWorker.class)), "workerRouter");
@Override
public Receive createReceive() {
return receiveBuilder()
.match(StatsJob.class, job -> !job.getText().isEmpty(), job -> {
String[] words = job.getText().split(" ");
ActorRef replyTo = getSender();
.match(
StatsJob.class,
job -> !job.getText().isEmpty(),
job -> {
String[] words = job.getText().split(" ");
ActorRef replyTo = getSender();
// create actor that collects replies from workers
ActorRef aggregator = getContext().actorOf(
Props.create(StatsAggregator.class, words.length, replyTo));
// create actor that collects replies from workers
ActorRef aggregator =
getContext().actorOf(Props.create(StatsAggregator.class, words.length, replyTo));
// send each word to a worker
for (String word : words) {
workerRouter.tell(new ConsistentHashableEnvelope(word, word),
aggregator);
}
})
.build();
// send each word to a worker
for (String word : words) {
workerRouter.tell(new ConsistentHashableEnvelope(word, word), aggregator);
}
})
.build();
}
}
//#service
// #service
//not used, only for documentation
// not used, only for documentation
abstract class StatsService2 extends AbstractActor {
//#router-lookup-in-code
// #router-lookup-in-code
int totalInstances = 100;
Iterable<String> routeesPaths = Collections
.singletonList("/user/statsWorker");
Iterable<String> routeesPaths = Collections.singletonList("/user/statsWorker");
boolean allowLocalRoutees = true;
Set<String> useRoles = new HashSet<>(Arrays.asList("compute"));
ActorRef workerRouter = getContext().actorOf(
new ClusterRouterGroup(new ConsistentHashingGroup(routeesPaths),
new ClusterRouterGroupSettings(totalInstances, routeesPaths,
allowLocalRoutees, useRoles)).props(), "workerRouter2");
//#router-lookup-in-code
ActorRef workerRouter =
getContext()
.actorOf(
new ClusterRouterGroup(
new ConsistentHashingGroup(routeesPaths),
new ClusterRouterGroupSettings(
totalInstances, routeesPaths, allowLocalRoutees, useRoles))
.props(),
"workerRouter2");
// #router-lookup-in-code
}
//not used, only for documentation
// not used, only for documentation
abstract class StatsService3 extends AbstractActor {
//#router-deploy-in-code
// #router-deploy-in-code
int totalInstances = 100;
int maxInstancesPerNode = 3;
boolean allowLocalRoutees = false;
Set<String> useRoles = new HashSet<>(Arrays.asList("compute"));
ActorRef workerRouter = getContext().actorOf(
new ClusterRouterPool(new ConsistentHashingPool(0),
new ClusterRouterPoolSettings(totalInstances, maxInstancesPerNode,
allowLocalRoutees, useRoles)).props(Props
.create(StatsWorker.class)), "workerRouter3");
//#router-deploy-in-code
ActorRef workerRouter =
getContext()
.actorOf(
new ClusterRouterPool(
new ConsistentHashingPool(0),
new ClusterRouterPoolSettings(
totalInstances, maxInstancesPerNode, allowLocalRoutees, useRoles))
.props(Props.create(StatsWorker.class)),
"workerRouter3");
// #router-deploy-in-code
}

View file

@ -9,7 +9,7 @@ import java.util.Map;
import akka.actor.AbstractActor;
//#worker
// #worker
public class StatsWorker extends AbstractActor {
Map<String, Integer> cache = new HashMap<String, Integer>();
@ -17,15 +17,17 @@ public class StatsWorker extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(String.class, word -> {
Integer length = cache.get(word);
if (length == null) {
length = word.length();
cache.put(word, length);
}
getSender().tell(length, getSelf());
})
.build();
.match(
String.class,
word -> {
Integer length = cache.get(word);
if (length == null) {
length = word.length();
cache.put(word, length);
}
getSender().tell(length, getSelf());
})
.build();
}
}
//#worker
// #worker

View file

@ -14,18 +14,18 @@ import akka.cluster.ClusterEvent.MemberUp;
import akka.cluster.Member;
import akka.cluster.MemberStatus;
//#backend
// #backend
public class TransformationBackend extends AbstractActor {
Cluster cluster = Cluster.get(getContext().getSystem());
//subscribe to cluster changes, MemberUp
// subscribe to cluster changes, MemberUp
@Override
public void preStart() {
cluster.subscribe(getSelf(), MemberUp.class);
}
//re-subscribe when restart
// re-subscribe when restart
@Override
public void postStop() {
cluster.unsubscribe(getSelf());
@ -34,27 +34,33 @@ public class TransformationBackend extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(TransformationJob.class, job -> {
getSender().tell(new TransformationResult(job.getText().toUpperCase()),
getSelf());
})
.match(CurrentClusterState.class, state -> {
for (Member member : state.getMembers()) {
if (member.status().equals(MemberStatus.up())) {
register(member);
}
}
})
.match(MemberUp.class, mUp -> {
register(mUp.member());
})
.build();
.match(
TransformationJob.class,
job -> {
getSender().tell(new TransformationResult(job.getText().toUpperCase()), getSelf());
})
.match(
CurrentClusterState.class,
state -> {
for (Member member : state.getMembers()) {
if (member.status().equals(MemberStatus.up())) {
register(member);
}
}
})
.match(
MemberUp.class,
mUp -> {
register(mUp.member());
})
.build();
}
void register(Member member) {
if (member.hasRole("frontend"))
getContext().actorSelection(member.address() + "/user/frontend").tell(
BACKEND_REGISTRATION, getSelf());
getContext()
.actorSelection(member.address() + "/user/frontend")
.tell(BACKEND_REGISTRATION, getSelf());
}
}
//#backend
// #backend

View file

@ -15,7 +15,7 @@ import akka.actor.ActorRef;
import akka.actor.Terminated;
import akka.actor.AbstractActor;
//#frontend
// #frontend
public class TransformationFrontend extends AbstractActor {
List<ActorRef> backends = new ArrayList<ActorRef>();
@ -24,25 +24,31 @@ public class TransformationFrontend extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.match(TransformationJob.class, job -> backends.isEmpty(), job -> {
getSender().tell(
new JobFailed("Service unavailable, try again later", job),
getSender());
})
.match(TransformationJob.class, job -> {
jobCounter++;
backends.get(jobCounter % backends.size())
.forward(job, getContext());
})
.matchEquals(BACKEND_REGISTRATION, x -> {
getContext().watch(getSender());
backends.add(getSender());
})
.match(Terminated.class, terminated -> {
backends.remove(terminated.getActor());
})
.build();
.match(
TransformationJob.class,
job -> backends.isEmpty(),
job -> {
getSender()
.tell(new JobFailed("Service unavailable, try again later", job), getSender());
})
.match(
TransformationJob.class,
job -> {
jobCounter++;
backends.get(jobCounter % backends.size()).forward(job, getContext());
})
.matchEquals(
BACKEND_REGISTRATION,
x -> {
getContext().watch(getSender());
backends.add(getSender());
})
.match(
Terminated.class,
terminated -> {
backends.remove(terminated.getActor());
})
.build();
}
}
//#frontend
// #frontend

View file

@ -6,7 +6,7 @@ package jdocs.cluster;
import java.io.Serializable;
//#messages
// #messages
public interface TransformationMessages {
public static class TransformationJob implements Serializable {
@ -62,6 +62,5 @@ public interface TransformationMessages {
}
public static final String BACKEND_REGISTRATION = "BackendRegistration";
}
//#messages
// #messages

View file

@ -9,23 +9,26 @@ import akka.actor.ActorRef;
import akka.actor.Props;
import akka.actor.SupervisorStrategy;
//#singleton-supervisor-actor-usage-imports
// #singleton-supervisor-actor-usage-imports
import akka.actor.PoisonPill;
import akka.actor.Props;
import akka.cluster.singleton.ClusterSingletonManager;
import akka.cluster.singleton.ClusterSingletonManagerSettings;
//#singleton-supervisor-actor-usage-imports
// #singleton-supervisor-actor-usage-imports
abstract class ClusterSingletonSupervision extends AbstractActor {
public ActorRef createSingleton(String name, Props props, SupervisorStrategy supervisorStrategy) {
//#singleton-supervisor-actor-usage
return getContext().system().actorOf(
ClusterSingletonManager.props(
Props.create(SupervisorActor.class, () -> new SupervisorActor(props, supervisorStrategy)),
PoisonPill.getInstance(),
ClusterSingletonManagerSettings.create(getContext().system())),
name = name);
//#singleton-supervisor-actor-usage
// #singleton-supervisor-actor-usage
return getContext()
.system()
.actorOf(
ClusterSingletonManager.props(
Props.create(
SupervisorActor.class, () -> new SupervisorActor(props, supervisorStrategy)),
PoisonPill.getInstance(),
ClusterSingletonManagerSettings.create(getContext().system())),
name = name);
// #singleton-supervisor-actor-usage
}
}
}

View file

@ -4,7 +4,7 @@
package jdocs.cluster.singleton;
//#singleton-supervisor-actor
// #singleton-supervisor-actor
import akka.actor.AbstractActor;
import akka.actor.AbstractActor.Receive;
import akka.actor.ActorRef;
@ -15,6 +15,7 @@ public class SupervisorActor extends AbstractActor {
final Props childProps;
final SupervisorStrategy supervisorStrategy;
final ActorRef child;
SupervisorActor(Props childProps, SupervisorStrategy supervisorStrategy) {
this.childProps = childProps;
this.supervisorStrategy = supervisorStrategy;
@ -28,9 +29,7 @@ public class SupervisorActor extends AbstractActor {
@Override
public Receive createReceive() {
return receiveBuilder()
.matchAny(msg -> child.forward(msg, getContext()))
.build();
return receiveBuilder().matchAny(msg -> child.forward(msg, getContext())).build();
}
}
//#singleton-supervisor-actor
// #singleton-supervisor-actor