in twill-discovery-core/src/main/java/org/apache/twill/discovery/ZKDiscoveryService.java [197:240]
private void handleRegisterFailure(final Discoverable discoverable,
final SettableFuture<String> completion,
final FutureCallback<String> creationCallback,
final Throwable failureCause) {
final String path = getNodePath(discoverable);
Futures.addCallback(zkClient.exists(path), new FutureCallback<Stat>() {
@Override
public void onSuccess(Stat result) {
if (result == null) {
// If the node is gone, simply retry.
LOG.info("Node {} is gone. Retry registration for {}.", path, discoverable);
retryRegister(discoverable, creationCallback);
return;
}
long ephemeralOwner = result.getEphemeralOwner();
if (ephemeralOwner == 0) {
// it is not an ephemeral node, something wrong.
LOG.error("Node {} already exists and is not an ephemeral node. Discoverable registration failed: {}.",
path, discoverable);
completion.setException(failureCause);
return;
}
Long sessionId = zkClient.getSessionId();
if (sessionId == null || ephemeralOwner != sessionId) {
// This zkClient is not valid or doesn't own the ephemeral node, simply keep retrying.
LOG.info("Owner of {} is different. Retry registration for {}.", path, discoverable);
retryRegister(discoverable, creationCallback);
} else {
// This client owned the node, treat the registration as completed.
// This could happen if same client tries to register twice (due to mistake or failure race condition).
completion.set(path);
}
}
@Override
public void onFailure(Throwable t) {
// If exists call failed, simply retry creation.
LOG.warn("Error when getting stats on {}. Retry registration for {}.", path, discoverable);
retryRegister(discoverable, creationCallback);
}
}, Threads.SAME_THREAD_EXECUTOR);
}