in src/main/java/com/uber/rss/metadata/ZooKeeperServiceRegistry.java [91:151]
public synchronized void registerServer(String dataCenter, String cluster, String serverId, String runningVersion, String connectionString) {
if (StringUtils.isBlank(dataCenter)) {
throw new IllegalArgumentException(String.format("Invalid input: dataCenter=%s", dataCenter));
}
if (StringUtils.isBlank(cluster)) {
throw new IllegalArgumentException(String.format("Invalid input: cluster=%s", cluster));
}
if (StringUtils.isBlank(serverId)) {
throw new IllegalArgumentException(String.format("Invalid input: serverId=%s", serverId));
}
if (StringUtils.isBlank(runningVersion)) {
throw new IllegalArgumentException(String.format("Invalid input: runningVersion=%s", runningVersion));
}
if (StringUtils.isBlank(connectionString)) {
throw new IllegalArgumentException(String.format("Invalid input: connectionString=%s", connectionString));
}
final String nodeName = getNodeName(serverId);
final String nodePath = getNodePath(dataCenter, cluster, nodeName);
final ZooKeeperServerNodeData nodeData = new ZooKeeperServerNodeData();
nodeData.setRunningVersion(runningVersion);
nodeData.setConnectionString(connectionString);
final byte[] nodeDataBytes = JsonUtils.serialize(nodeData).getBytes(StandardCharsets.UTF_8);
// Two loops because first loop will only fail in the unlikely situation that the ephemeral node already exists
// and needs to be deleted before trying again.
for (int i = 0; i < 2; i++) {
try {
zk.create()
.creatingParentsIfNeeded()
.withMode(CreateMode.EPHEMERAL)
.withACL(ZooDefs.Ids.OPEN_ACL_UNSAFE)
.forPath(nodePath, nodeDataBytes);
return;
} catch (KeeperException.NodeExistsException nee) {
if (i == 1) {
M3Stats.addException(nee, this.getClass().getSimpleName());
// This is only a problem on the second attempt
throw new RssException("Unable to register ZooKeeper node " + nodePath, nee);
}
logger.info("ZooKeeper node already exists: " + nodePath, nee);
try {
// Need to delete it so that the ephemeral node remains tied to the lifetime of this connection
zk.delete().forPath(nodePath);
} catch (KeeperException.NoNodeException nne) {
// It's a race condition, but it's fine provided that *somebody* deleted it. Try again.
} catch (Exception e) {
M3Stats.addException(e, this.getClass().getSimpleName());
throw new RssException("Unable to delete existing ZooKeeper node " + nodePath, e);
}
} catch (Exception e) {
M3Stats.addException(e, this.getClass().getSimpleName());
throw new RssException("Unable to create ZooKeeper node " + nodePath, e);
}
}
throw new RssException("Too many failures trying to register the node");
}