My setup was a Spring-enabled server that used Hazelcast as a datagrid for the caching of various data structures (but also to act as 2nd level cache for Hibernate). So the idea was to use Hazelcast for leader election, since the Hazelcast cluster automagically will grow/shrink as the size of my cluster changed and thus Hazelcast will always know the size of the cluster and its members.
So is there a simple way through which we can use Hazelcast for leader election?
/**
* Leader election is the process of designating a
* single node as the organizer of some distributed
* task among several nodes in the cluster.
*
* @author Andreas Lindfalk
*/
public interface LeaderElection {
/**
* Get whether this node is the leader
* in the cluster or not.
*
* @return {@code true} if it is this node
* that is the leader, else {@code false}
*/
boolean isLeader();
}
The implementation simply selects the oldest member in the Hazelcast cluster as the leader, and this code will check if the current node is in fact that oldest and therefore leading node:
/**
* A simple leader election implementation based on
* a Hazelcast cluster that simply elects the oldest
* member in the cluster as the leader.
*
* @author Andreas Lindfalk
*/
@Component
public class HazelcastLeaderElection
implements LeaderElection {
@Resource
private HazelcastInstance instance;
/**
* {@inheritDoc}
*/
@Override
public boolean isLeader() {
// The first member in the set is the
// oldest member, this is the one that
// we always will point out as leader
Member oldestMember = instance.getCluster()
.getMembers().iterator().next();
return oldestMember.localMember();
}
}
So now in the scheduled and recurring task I can now check whether the current node is the leader in the cluster or not, and based on this either proceed and perform the task or step back and let the leader take care of it.
@Component
public class WeatherSchedulerImpl
implements WeatherScheduler {
@Resource
private LeaderElection leaderElection;
/**
* {@inheritDoc}
*/
@Override
@Scheduled(
initialDelayString = "10000",
fixedDelayString = "900000")
public void retrieveWeather() {
if (leaderElection.isLeader()) {
// Fetch the weather data...
}
}
}