Skip to content

Instantly share code, notes, and snippets.

@kay
Last active December 17, 2015 18:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kay/5652901 to your computer and use it in GitHub Desktop.
Save kay/5652901 to your computer and use it in GitHub Desktop.
package org.neverfear.ha;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import org.jgroups.JChannel;
import org.jgroups.blocks.locking.LockService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Resolves who will be leader through the use of a distributed lock.
*
* Should not be called from multiple threads at once (not thread safe).
*/
class LeadershipResolver {
private static final Logger LOGGER = LoggerFactory.getLogger(LeadershipResolver.class);
private static final String LOCK_NAME_FORMAT = "ha-%s";
private final String lockName;
private final Lock leaderLock;
private final LeadershipListener leadershipListener;
private final AtomicBoolean leader = new AtomicBoolean(false);
public LeadershipResolver(
final JChannel channel,
final String name,
final LeadershipListener leadershipListener) {
this.lockName = String.format(LOCK_NAME_FORMAT, name);
final LockService lockService = new LockService(channel);
this.leaderLock = lockService.getLock(this.lockName);
this.leadershipListener = leadershipListener;
}
public void tryLeadership() {
LOGGER.info("Trying for lock");
if (this.leaderLock.tryLock()) {
LOGGER.info("Got lock");
setLeader(true);
} else {
LOGGER.info("Failed");
setLeader(false);
}
}
public void surrenderLeadership() {
this.leaderLock.unlock();
setLeader(false);
}
public void close() {
surrenderLeadership();
}
public boolean isLeader() {
return this.leader.get();
}
private void setLeader(final boolean leader) {
if (leader) {
if (this.leader.compareAndSet(false, true)) {
LOGGER.info("Acquired leadership");
this.leadershipListener.onAcquired();
}
} else {
if (this.leader.compareAndSet(true, false)) {
LOGGER.info("Relinquishing leadership");
this.leadershipListener.onRelinquished();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment