2017-02-14 13:10:23 +02:00
|
|
|
package docs.cluster;
|
2012-10-04 14:12:48 +02:00
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.HashSet;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
|
2017-02-14 13:10:23 +02:00
|
|
|
import docs.cluster.StatsMessages.JobFailed;
|
|
|
|
|
import docs.cluster.StatsMessages.StatsJob;
|
|
|
|
|
import docs.cluster.StatsMessages.StatsResult;
|
2015-09-25 08:39:02 +02:00
|
|
|
import java.util.concurrent.ThreadLocalRandom;
|
2012-10-15 17:17:54 +02:00
|
|
|
import scala.concurrent.duration.Duration;
|
|
|
|
|
import scala.concurrent.duration.FiniteDuration;
|
2013-03-26 18:17:50 +01:00
|
|
|
import akka.actor.ActorSelection;
|
2012-10-04 14:12:48 +02:00
|
|
|
import akka.actor.Address;
|
|
|
|
|
import akka.actor.Cancellable;
|
2017-02-23 00:50:07 +05:00
|
|
|
import akka.actor.AbstractActor;
|
2012-10-04 14:12:48 +02:00
|
|
|
import akka.cluster.Cluster;
|
2014-01-08 14:14:48 +01:00
|
|
|
import akka.cluster.ClusterEvent.UnreachableMember;
|
|
|
|
|
import akka.cluster.ClusterEvent.ReachableMember;
|
2012-10-04 14:12:48 +02:00
|
|
|
import akka.cluster.ClusterEvent.CurrentClusterState;
|
|
|
|
|
import akka.cluster.ClusterEvent.MemberEvent;
|
|
|
|
|
import akka.cluster.ClusterEvent.MemberUp;
|
2014-01-08 14:14:48 +01:00
|
|
|
import akka.cluster.ClusterEvent.ReachabilityEvent;
|
2012-10-04 14:12:48 +02:00
|
|
|
import akka.cluster.Member;
|
|
|
|
|
import akka.cluster.MemberStatus;
|
|
|
|
|
|
2017-02-23 00:50:07 +05:00
|
|
|
public class StatsSampleClient extends AbstractActor {
|
2012-10-04 14:12:48 +02:00
|
|
|
|
|
|
|
|
final String servicePath;
|
|
|
|
|
final Cancellable tickTask;
|
|
|
|
|
final Set<Address> nodes = new HashSet<Address>();
|
|
|
|
|
|
|
|
|
|
Cluster cluster = Cluster.get(getContext().system());
|
|
|
|
|
|
|
|
|
|
public StatsSampleClient(String servicePath) {
|
|
|
|
|
this.servicePath = servicePath;
|
|
|
|
|
FiniteDuration interval = Duration.create(2, TimeUnit.SECONDS);
|
|
|
|
|
tickTask = getContext()
|
|
|
|
|
.system()
|
|
|
|
|
.scheduler()
|
2017-02-23 00:50:07 +05:00
|
|
|
.schedule(interval, interval, self(), "tick",
|
2012-12-18 00:51:11 +01:00
|
|
|
getContext().dispatcher(), null);
|
2012-10-04 14:12:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//subscribe to cluster changes, MemberEvent
|
|
|
|
|
@Override
|
|
|
|
|
public void preStart() {
|
2014-01-08 14:14:48 +01:00
|
|
|
cluster.subscribe(getSelf(), MemberEvent.class, ReachabilityEvent.class);
|
2012-10-04 14:12:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//re-subscribe when restart
|
|
|
|
|
@Override
|
|
|
|
|
public void postStop() {
|
2017-02-23 00:50:07 +05:00
|
|
|
cluster.unsubscribe(self());
|
2012-10-04 14:12:48 +02:00
|
|
|
tickTask.cancel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2017-02-23 00:50:07 +05:00
|
|
|
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(
|
2012-10-04 14:12:48 +02:00
|
|
|
nodesList.size()));
|
2017-02-23 00:50:07 +05:00
|
|
|
ActorSelection service = getContext().actorSelection(address + servicePath);
|
|
|
|
|
service.tell(new StatsJob("this is the text that will be analyzed"),
|
|
|
|
|
self());
|
|
|
|
|
})
|
|
|
|
|
.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());
|
|
|
|
|
}
|
2012-10-04 14:12:48 +02:00
|
|
|
}
|
2017-02-23 00:50:07 +05:00
|
|
|
})
|
|
|
|
|
.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();
|
2012-10-04 14:12:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|