|
@@ -43,7 +43,6 @@ import java.net.URISyntaxException;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collection;
|
|
|
import java.util.EnumSet;
|
|
|
-import java.util.HashSet;
|
|
|
import java.util.LinkedHashMap;
|
|
|
import java.util.LinkedHashSet;
|
|
|
import java.util.List;
|
|
@@ -671,8 +670,8 @@ public class RouterRpcServer extends AbstractService implements ClientProtocol,
|
|
|
|
|
|
/**
|
|
|
* Invokes the method at default namespace, if default namespace is not
|
|
|
- * available then at the first available namespace.
|
|
|
- * If the namespace is unavailable, retry once with other namespace.
|
|
|
+ * available then at the other available namespaces.
|
|
|
+ * If the namespace is unavailable, retry with other namespaces.
|
|
|
* @param <T> expected return type.
|
|
|
* @param method the remote method.
|
|
|
* @return the response received after invoking method.
|
|
@@ -681,28 +680,29 @@ public class RouterRpcServer extends AbstractService implements ClientProtocol,
|
|
|
<T> T invokeAtAvailableNs(RemoteMethod method, Class<T> clazz)
|
|
|
throws IOException {
|
|
|
String nsId = subclusterResolver.getDefaultNamespace();
|
|
|
- // If default Ns is not present return result from first namespace.
|
|
|
Set<FederationNamespaceInfo> nss = namenodeResolver.getNamespaces();
|
|
|
- try {
|
|
|
- if (!nsId.isEmpty()) {
|
|
|
+ // If no namespace is available, then throw this IOException.
|
|
|
+ IOException io = new IOException("No namespace available.");
|
|
|
+ // If default Ns is present return result from that namespace.
|
|
|
+ if (!nsId.isEmpty()) {
|
|
|
+ try {
|
|
|
return rpcClient.invokeSingle(nsId, method, clazz);
|
|
|
+ } catch (IOException ioe) {
|
|
|
+ if (!clientProto.isUnavailableSubclusterException(ioe)) {
|
|
|
+ LOG.debug("{} exception cannot be retried",
|
|
|
+ ioe.getClass().getSimpleName());
|
|
|
+ throw ioe;
|
|
|
+ }
|
|
|
+ // Remove the already tried namespace.
|
|
|
+ nss.removeIf(n -> n.getNameserviceId().equals(nsId));
|
|
|
+ return invokeOnNs(method, clazz, io, nss);
|
|
|
}
|
|
|
- // If no namespace is available, throw IOException.
|
|
|
- IOException io = new IOException("No namespace available.");
|
|
|
- return invokeOnNs(method, clazz, io, nss);
|
|
|
- } catch (IOException ioe) {
|
|
|
- if (!clientProto.isUnavailableSubclusterException(ioe)) {
|
|
|
- LOG.debug("{} exception cannot be retried",
|
|
|
- ioe.getClass().getSimpleName());
|
|
|
- throw ioe;
|
|
|
- }
|
|
|
- Set<FederationNamespaceInfo> nssWithoutFailed = getNameSpaceInfo(nss, nsId);
|
|
|
- return invokeOnNs(method, clazz, ioe, nssWithoutFailed);
|
|
|
}
|
|
|
+ return invokeOnNs(method, clazz, io, nss);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Invoke the method on first available namespace,
|
|
|
+ * Invoke the method sequentially on available namespaces,
|
|
|
* throw no namespace available exception, if no namespaces are available.
|
|
|
* @param method the remote method.
|
|
|
* @param clazz Class for the return type.
|
|
@@ -716,26 +716,22 @@ public class RouterRpcServer extends AbstractService implements ClientProtocol,
|
|
|
if (nss.isEmpty()) {
|
|
|
throw ioe;
|
|
|
}
|
|
|
- String nsId = nss.iterator().next().getNameserviceId();
|
|
|
- return rpcClient.invokeSingle(nsId, method, clazz);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Get set of namespace info's removing the already invoked namespaceinfo.
|
|
|
- * @param nss List of namespaces in the federation.
|
|
|
- * @param nsId Already invoked namespace id.
|
|
|
- * @return List of name spaces in the federation on
|
|
|
- * removing the already invoked namespaceinfo.
|
|
|
- */
|
|
|
- private static Set<FederationNamespaceInfo> getNameSpaceInfo(
|
|
|
- final Set<FederationNamespaceInfo> nss, final String nsId) {
|
|
|
- Set<FederationNamespaceInfo> namespaceInfos = new HashSet<>();
|
|
|
- for (FederationNamespaceInfo ns : nss) {
|
|
|
- if (!nsId.equals(ns.getNameserviceId())) {
|
|
|
- namespaceInfos.add(ns);
|
|
|
+ for (FederationNamespaceInfo fnInfo : nss) {
|
|
|
+ String nsId = fnInfo.getNameserviceId();
|
|
|
+ LOG.debug("Invoking {} on namespace {}", method, nsId);
|
|
|
+ try {
|
|
|
+ return rpcClient.invokeSingle(nsId, method, clazz);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.debug("Failed to invoke {} on namespace {}", method, nsId, e);
|
|
|
+ // Ignore the exception and try on other namespace, if the tried
|
|
|
+ // namespace is unavailable, else throw the received exception.
|
|
|
+ if (!clientProto.isUnavailableSubclusterException(e)) {
|
|
|
+ throw e;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- return namespaceInfos;
|
|
|
+ // Couldn't get a response from any of the namespace, throw ioe.
|
|
|
+ throw ioe;
|
|
|
}
|
|
|
|
|
|
@Override // ClientProtocol
|