Akka Java Tutorials Part 2- How to build a Scheduler using Akka Cluster Singleton & Akka Scheduler

gaurav ranjan
3 min readNov 4, 2019

--

As part of akka java tutorials series in Part 1 I discussed akka distributed data module. In this part I would be covering Cluster Singleton module. Along with it I will show you how we can use it for building a robust, singleton and a fault tolerant scheduler for the application deployed in a cluster.

For some use cases it is convenient and sometimes also mandatory to ensure that we have exactly one actor of a certain type running somewhere in the cluster. Cluster Singleton module provides us with this very feature. It makes sure that exactly one singleton actor instance runs within a cluster. This becomes very handy for certain use cases one of which I am going to discuss below.

Cluster Singleton though looks very intimidating and tempting to use, but we need to be very careful while deploying it in the production environment. Some of the things which needs to be taken are mentioned here.

With this let us start with the code to set up a singleton actor in the application.

Step 1:

Create an actor like below. I will discuss the scheduler in some time. Kindly ignore for now. The name of our singleton actor is ClusterSingletonActor. The reference of this would be used in the next step.

public class ClusterSingletonActor extends UntypedAbstractActor {

ActorSystem actorSystem;
Cancellable singletonScheduler;
LoggingAdapter log;


public static Props props(ActorSystem actorSystem) {
return Props.create(ClusterSingletonActor.class,
actorSystem);
}

public ClusterSingletonActor(ActorSystem actorSystem) {
this.actorSystem = actorSystem;
this.log = Logging.getLogger(actorSystem, ClusterSingletonActor.class);

}

@Override
public void preStart() {
schedule();
}

@Override
public void onReceive(Object message) throws Throwable {
if (message instanceof ClusterMessages.SingletonScheduler) {
log.info("Scheduler ran after 20 seconds");
}
}

private void schedule() {
this.singletonScheduler = actorSystem.scheduler().schedule(
scala.concurrent.duration.Duration.create(new Random().nextInt(5), TimeUnit.SECONDS),
scala.concurrent.duration.Duration.create(20, TimeUnit.SECONDS),
new Runnable() {
@Override
public void run() {
self().tell(new ClusterMessages.SingletonScheduler(), ActorRef.noSender());
}
}, actorSystem.dispatcher()

);
}
}

Step 2:

Create a ClusterSingletonManagerSettings object to be used. These settings defines the configuration properties of the singleton actor. Details can be found here.

ClusterSingletonManagerSettings manageSettings = ClusterSingletonManagerSettings
.create(actorSystem).withSingletonName("ClusterSingletonActorManager").withHandOverRetryInterval(new FiniteDuration(6, TimeUnit.SECONDS))
.withRemovalMargin(new FiniteDuration(6, TimeUnit.SECONDS));

actorSystem.actorOf(ClusterSingletonManager
.props(ClusterSingletonActor
.props(actorSystem),
PoisonPill.getInstance(),
manageSettings),
"ClusterSingletonActorManager");

Step 3:

Create a ClusterSingletonProxySettings object. The singleton actor is always accessed by a proxy actor. Details can be found here.

ClusterSingletonProxySettings proxySettings = new ClusterSingletonProxySettings(
"ClusterSingletonActorManager", Option.empty(),
new FiniteDuration(1, TimeUnit.SECONDS), 1000);

actorSystem.actorOf(ClusterSingletonProxy.props(
"/user/" + "ClusterSingletonActorManager",
proxySettings),
"ClusterSingletonActorProxy");

With these steps the singleton actor would be initialised and ready for use. As you run the application we can see following logs.

00:10:52.550 [akka-java-tutorials-akka.actor.default-dispatcher-2] INFO akka.cluster.singleton.ClusterSingletonProxy - Singleton identified at [akka://akka-java-tutorials/user/ClusterSingletonActorManager/ClusterSingletonActorManager]

Fault Tolerance of Cluster Singleton

Akka framework guarantees the fault tolerance out of the box. Suppose if there is a jvm crash or the node running the singleton actor goes down the framework makes sure the actor gets started in one of the other nodes of the cluster. However, there would some delay before another singleton comes up.

Singleton Scheduler leveraging Cluster Singleton

Now, the singleton actor is setup. Let us see how we can use it to build our scheduler.

Well, there are many frameworks which are available for scheduling cron jobs. Akka Scheduler is a robust piece built in to run periodic jobs within the akka cluster. The periodic jobs could be like fetching data from DB , calling some web service periodically , etc.

The scheduler can be set up using the Cancellable Interface.

Cancellable singletonScheduler;

Next step is to schedule the job.

private void schedule() {
this.singletonScheduler = actorSystem.scheduler().schedule(
scala.concurrent.duration.Duration.create(new Random().nextInt(5), TimeUnit.SECONDS),
scala.concurrent.duration.Duration.create(20, TimeUnit.SECONDS),
new Runnable() {
@Override
public void run() {
self().tell(new ClusterMessages.SingletonScheduler(), ActorRef.noSender());
}
}, actorSystem.dispatcher()

);
}

In this example the runnable job just sends out a message to our singleton actor which in turn logs them.

@Override
public void onReceive(Object message) throws Throwable {
if (message instanceof ClusterMessages.SingletonScheduler) {
log.info("Scheduler ran after 20 seconds");
}
}

The Cluster Singleton make sure only one instance of the scheduler runs in the entire cluster making sure there are no duplicate cron jobs.

The complete code is available here.

Conclusion

In part 2 of the tutorial we saw how to combine the power of Cluster Singleton and AKKA scheduler to create robust, fault tolerant scheduler within a cluster to run our periodic jobs.

In the next series I will talk about AKKA Pub Sub module.

Stay Tuned!!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response