use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.
the class TabletServer method announceExistence.
private void announceExistence() {
ZooReaderWriter zoo = getContext().getZooReaderWriter();
try {
var zLockPath = ServiceLock.path(getContext().getZooKeeperRoot() + Constants.ZTSERVERS + "/" + getClientAddressString());
try {
zoo.putPersistentData(zLockPath.toString(), new byte[] {}, NodeExistsPolicy.SKIP);
} catch (KeeperException e) {
if (e.code() == KeeperException.Code.NOAUTH) {
log.error("Failed to write to ZooKeeper. Ensure that" + " accumulo.properties, specifically instance.secret, is consistent.");
}
throw e;
}
tabletServerLock = new ServiceLock(zoo.getZooKeeper(), zLockPath, UUID.randomUUID());
LockWatcher lw = new LockWatcher() {
@Override
public void lostLock(final LockLossReason reason) {
Halt.halt(serverStopRequested ? 0 : 1, () -> {
if (!serverStopRequested) {
log.error("Lost tablet server lock (reason = {}), exiting.", reason);
}
gcLogger.logGCInfo(getConfiguration());
});
}
@Override
public void unableToMonitorLockNode(final Exception e) {
Halt.halt(1, () -> log.error("Lost ability to monitor tablet server lock, exiting.", e));
}
};
byte[] lockContent = new ServerServices(getClientAddressString(), Service.TSERV_CLIENT).toString().getBytes(UTF_8);
for (int i = 0; i < 120 / 5; i++) {
zoo.putPersistentData(zLockPath.toString(), new byte[0], NodeExistsPolicy.SKIP);
if (tabletServerLock.tryLock(lw, lockContent)) {
log.debug("Obtained tablet server lock {}", tabletServerLock.getLockPath());
lockID = tabletServerLock.getLockID().serialize(getContext().getZooKeeperRoot() + Constants.ZTSERVERS + "/");
return;
}
log.info("Waiting for tablet server lock");
sleepUninterruptibly(5, TimeUnit.SECONDS);
}
String msg = "Too many retries, exiting.";
log.info(msg);
throw new RuntimeException(msg);
} catch (Exception e) {
log.info("Could not obtain tablet server lock, exiting.", e);
throw new RuntimeException(e);
}
}
use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.
the class Monitor method getMonitorLock.
/**
* Get the monitor lock in ZooKeeper
*/
private void getMonitorLock() throws KeeperException, InterruptedException {
ServerContext context = getContext();
final String zRoot = context.getZooKeeperRoot();
final String monitorPath = zRoot + Constants.ZMONITOR;
final var monitorLockPath = ServiceLock.path(zRoot + Constants.ZMONITOR_LOCK);
// Ensure that everything is kosher with ZK as this has changed.
ZooReaderWriter zoo = context.getZooReaderWriter();
if (zoo.exists(monitorPath)) {
byte[] data = zoo.getData(monitorPath);
// If the node isn't empty, it's from a previous install (has hostname:port for HTTP server)
if (data.length != 0) {
// Recursively delete from that parent node
zoo.recursiveDelete(monitorPath, NodeMissingPolicy.SKIP);
// And then make the nodes that we expect for the incoming ephemeral nodes
zoo.putPersistentData(monitorPath, new byte[0], NodeExistsPolicy.FAIL);
zoo.putPersistentData(monitorLockPath.toString(), new byte[0], NodeExistsPolicy.FAIL);
} else if (!zoo.exists(monitorLockPath.toString())) {
// monitor node in ZK exists and is empty as we expect
// but the monitor/lock node does not
zoo.putPersistentData(monitorLockPath.toString(), new byte[0], NodeExistsPolicy.FAIL);
}
} else {
// 1.5.0 and earlier
zoo.putPersistentData(zRoot + Constants.ZMONITOR, new byte[0], NodeExistsPolicy.FAIL);
if (!zoo.exists(monitorLockPath.toString())) {
// Somehow the monitor node exists but not monitor/lock
zoo.putPersistentData(monitorLockPath.toString(), new byte[0], NodeExistsPolicy.FAIL);
}
}
// Get a ZooLock for the monitor
UUID zooLockUUID = UUID.randomUUID();
while (true) {
MoniterLockWatcher monitorLockWatcher = new MoniterLockWatcher();
monitorLock = new ServiceLock(zoo.getZooKeeper(), monitorLockPath, zooLockUUID);
monitorLock.lock(monitorLockWatcher, new byte[0]);
monitorLockWatcher.waitForChange();
if (monitorLockWatcher.acquiredLock) {
break;
}
if (!monitorLockWatcher.failedToAcquireLock) {
throw new IllegalStateException("monitor lock in unknown state");
}
monitorLock.tryToCancelAsyncLockOrUnlock();
sleepUninterruptibly(context.getConfiguration().getTimeInMillis(Property.MONITOR_LOCK_CHECK_INTERVAL), TimeUnit.MILLISECONDS);
}
log.info("Got Monitor lock.");
}
use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.
the class ServiceLockIT method testTryLock.
@Test(timeout = 10000)
public void testTryLock() throws Exception {
var parent = ServiceLock.path("/zltestTryLock-" + this.hashCode() + "-l" + pdCount.incrementAndGet());
ServiceLock zl = getZooLock(parent, UUID.randomUUID());
ConnectedWatcher watcher = new ConnectedWatcher();
try (ZooKeeper zk = new ZooKeeper(szk.getConn(), 30000, watcher)) {
ZooUtil.digestAuth(zk, "secret");
while (!watcher.isConnected()) {
Thread.sleep(200);
}
for (int i = 0; i < 10; i++) {
zk.create(parent.toString(), new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.delete(parent.toString(), -1);
}
zk.create(parent.toString(), new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
TestALW lw = new TestALW();
boolean ret = zl.tryLock(lw, "test1".getBytes(UTF_8));
assertTrue(ret);
// make sure still watching parent even though a lot of events occurred for the parent
synchronized (zl) {
Field field = zl.getClass().getDeclaredField("watchingParent");
field.setAccessible(true);
assertTrue((Boolean) field.get(zl));
}
zl.unlock();
}
}
use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.
the class ServiceLockIT method testLockSerial.
@Test(timeout = 60000)
public void testLockSerial() throws Exception {
var parent = ServiceLock.path("/zlretryLockSerial");
ConnectedWatcher watcher1 = new ConnectedWatcher();
ConnectedWatcher watcher2 = new ConnectedWatcher();
try (ZooKeeperWrapper zk1 = new ZooKeeperWrapper(szk.getConn(), 30000, watcher1);
ZooKeeperWrapper zk2 = new ZooKeeperWrapper(szk.getConn(), 30000, watcher2)) {
ZooUtil.digestAuth(zk1, "secret");
ZooUtil.digestAuth(zk2, "secret");
while (!watcher1.isConnected()) {
Thread.sleep(200);
}
while (!watcher2.isConnected()) {
Thread.sleep(200);
}
// Create the parent node
zk1.createOnce(parent.toString(), new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
final RetryLockWatcher zlw1 = new RetryLockWatcher();
ServiceLock zl1 = getZooLock(zk1, parent, UUID.fromString("00000000-0000-0000-0000-aaaaaaaaaaaa"));
zl1.lock(zlw1, "test1".getBytes(UTF_8));
// The call above creates two nodes in ZK because of the overridden create method in
// ZooKeeperWrapper.
// The nodes created are:
// zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000
// zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000001
//
// ZooLock should realize this and remove the latter one and place a watcher on the first one
// in case the ZooKeeper ephemeral node is deleted by some external process.
// Lastly, because zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000 is the first child,
// zl1 assumes that it has the lock.
final RetryLockWatcher zlw2 = new RetryLockWatcher();
ServiceLock zl2 = getZooLock(zk2, parent, UUID.fromString("00000000-0000-0000-0000-bbbbbbbbbbbb"));
zl2.lock(zlw2, "test1".getBytes(UTF_8));
// The call above creates two nodes in ZK because of the overridden create method in
// ZooKeeperWrapper.
// The nodes created are:
// zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000002
// zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000003
//
// ZooLock should realize this and remove the latter one and place a watcher on the first one
// in case
// the ZooKeeper ephemeral node is deleted by some external process.
// Because zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000002 is not the first child in the
// list, it places a watcher on zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000
// so that it may try to acquire the lock when
// zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000 is removed.
assertTrue(zlw1.isLockHeld());
assertFalse(zlw2.isLockHeld());
List<String> children = zk1.getChildren(parent.toString(), false);
assertTrue(children.contains("zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000"));
assertFalse("this node should have been deleted", children.contains("zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000001"));
assertTrue(children.contains("zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000002"));
assertFalse("this node should have been deleted", children.contains("zlock#00000000-0000-0000-0000-bbbbbbbbbbbb#0000000003"));
assertNull(zl1.getWatching());
assertEquals("/zlretryLockSerial/zlock#00000000-0000-0000-0000-aaaaaaaaaaaa#0000000000", zl2.getWatching());
zl1.unlock();
assertFalse(zlw1.isLockHeld());
zk1.close();
while (!zlw2.isLockHeld()) {
LockSupport.parkNanos(50);
}
assertTrue(zlw2.isLockHeld());
zl2.unlock();
zk2.close();
}
}
use of org.apache.accumulo.fate.zookeeper.ServiceLock in project accumulo by apache.
the class ServiceLockIT method testDeleteLock.
@Test(timeout = 10000)
public void testDeleteLock() throws Exception {
var parent = ServiceLock.path("/zltestDeleteLock-" + this.hashCode() + "-l" + pdCount.incrementAndGet());
ZooReaderWriter zk = new ZooReaderWriter(szk.getConn(), 30000, "secret");
zk.mkdirs(parent.toString());
ServiceLock zl = getZooLock(parent, UUID.randomUUID());
assertFalse(zl.isLocked());
TestALW lw = new TestALW();
zl.lock(lw, "test1".getBytes(UTF_8));
lw.waitForChanges(1);
assertTrue(lw.locked);
assertTrue(zl.isLocked());
assertNull(lw.exception);
assertNull(lw.reason);
zk.delete(zl.getLockPath());
lw.waitForChanges(2);
assertEquals(LockLossReason.LOCK_DELETED, lw.reason);
assertNull(lw.exception);
}
Aggregations