YARN-8600. RegistryDNS hang when remote lookup does not reply. Contributed by Eric Yang
This commit is contained in:
parent
67c65da261
commit
603a57476c
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.hadoop.registry.server.dns;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.xbill.DNS.Lookup;
|
||||
import org.xbill.DNS.Name;
|
||||
import org.xbill.DNS.Record;
|
||||
|
||||
public class LookupTask implements Callable<Record[]> {
|
||||
|
||||
private Name name;
|
||||
private int type;
|
||||
|
||||
public LookupTask(Name name, int type) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Record[] call() throws Exception {
|
||||
return new Lookup(name, type).run();
|
||||
}
|
||||
}
|
|
@ -99,9 +99,13 @@ import java.util.Properties;
|
|||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
@ -941,7 +945,7 @@ public class RegistryDNS extends AbstractService implements DNSOperations,
|
|||
* @param port local port.
|
||||
* @throws IOException if the UDP processing fails.
|
||||
*/
|
||||
private void serveNIOUDP(DatagramChannel channel,
|
||||
private synchronized void serveNIOUDP(DatagramChannel channel,
|
||||
InetAddress addr, int port) throws Exception {
|
||||
SocketAddress remoteAddress = null;
|
||||
try {
|
||||
|
@ -1177,13 +1181,20 @@ public class RegistryDNS extends AbstractService implements DNSOperations,
|
|||
* @return DNS records
|
||||
*/
|
||||
protected Record[] getRecords(Name name, int type) {
|
||||
Record[] result = null;
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
Future<Record[]> future = executor.submit(new LookupTask(name, type));
|
||||
try {
|
||||
return new Lookup(name, type).run();
|
||||
} catch (NullPointerException |
|
||||
result = future.get(1500, TimeUnit.MILLISECONDS);
|
||||
return result;
|
||||
} catch (InterruptedException | ExecutionException |
|
||||
TimeoutException | NullPointerException |
|
||||
ExceptionInInitializerError e) {
|
||||
LOG.error("Fail to lookup: " + name, e);
|
||||
LOG.warn("Failed to lookup: {} type: {}", name, Type.string(type), e);
|
||||
return result;
|
||||
} finally {
|
||||
executor.shutdown();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -697,6 +697,14 @@ public class TestRegistryDNS extends Assert {
|
|||
assertTrue("not an ARecord", recs[0] instanceof ARecord);
|
||||
assertTrue("not an ARecord", recs[1] instanceof ARecord);
|
||||
}
|
||||
|
||||
@Test(timeout=5000)
|
||||
public void testUpstreamFault() throws Exception {
|
||||
Name name = Name.fromString("19.0.17.172.in-addr.arpa.");
|
||||
Record[] recs = getRegistryDNS().getRecords(name, Type.CNAME);
|
||||
assertNull("Record is not null", recs);
|
||||
}
|
||||
|
||||
public RegistryDNS getRegistryDNS() {
|
||||
return registryDNS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue