Fix another resource leak in DnsNameResolver
- Fix a bug in cache expiration task; wrong object was being released - Added more sanity checks when caching an entry
This commit is contained in:
parent
e809f97136
commit
29a847587f
@ -726,14 +726,17 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cache(final DnsQuestion question, DnsCacheEntry entry, long delaySeconds) {
|
void cache(final DnsQuestion question, DnsCacheEntry entry, long delaySeconds) {
|
||||||
queryCache.put(question, entry);
|
DnsCacheEntry oldEntry = queryCache.put(question, entry);
|
||||||
|
if (oldEntry != null) {
|
||||||
|
oldEntry.release();
|
||||||
|
}
|
||||||
|
|
||||||
boolean scheduled = false;
|
boolean scheduled = false;
|
||||||
try {
|
try {
|
||||||
entry.expirationFuture = ch.eventLoop().schedule(new OneTimeTask() {
|
entry.expirationFuture = ch.eventLoop().schedule(new OneTimeTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Object response = queryCache.remove(question);
|
clearCache(question);
|
||||||
ReferenceCountUtil.safeRelease(response);
|
|
||||||
}
|
}
|
||||||
}, delaySeconds, TimeUnit.SECONDS);
|
}, delaySeconds, TimeUnit.SECONDS);
|
||||||
|
|
||||||
@ -742,7 +745,7 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
|||||||
if (!scheduled) {
|
if (!scheduled) {
|
||||||
// If failed to schedule the expiration task,
|
// If failed to schedule the expiration task,
|
||||||
// remove the entry from the cache so that it does not leak.
|
// remove the entry from the cache so that it does not leak.
|
||||||
queryCache.remove(question);
|
clearCache(question);
|
||||||
entry.release();
|
entry.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -789,12 +792,16 @@ public class DnsNameResolver extends SimpleNameResolver<InetSocketAddress> {
|
|||||||
if (res.header().responseCode() == DnsResponseCode.NOERROR) {
|
if (res.header().responseCode() == DnsResponseCode.NOERROR) {
|
||||||
cache(q, res);
|
cache(q, res);
|
||||||
promises.set(queryId, null);
|
promises.set(queryId, null);
|
||||||
qCtx.promise().trySuccess(res.retain());
|
|
||||||
|
Promise<DnsResponse> qPromise = qCtx.promise();
|
||||||
|
if (qPromise.setUncancellable()) {
|
||||||
|
qPromise.setSuccess(res.retain());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
qCtx.retry(res.sender(),
|
qCtx.retry(res.sender(),
|
||||||
"response code: " + res.header().responseCode() +
|
"response code: " + res.header().responseCode() +
|
||||||
" with " + res.answers().size() + " answer(s) and " +
|
" with " + res.answers().size() + " answer(s) and " +
|
||||||
res.authorityResources().size() + " authority resource(s)");
|
res.authorityResources().size() + " authority resource(s)");
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
ReferenceCountUtil.safeRelease(msg);
|
ReferenceCountUtil.safeRelease(msg);
|
||||||
|
@ -30,8 +30,8 @@ import io.netty.util.internal.StringUtil;
|
|||||||
import io.netty.util.internal.ThreadLocalRandom;
|
import io.netty.util.internal.ThreadLocalRandom;
|
||||||
import io.netty.util.internal.logging.InternalLogger;
|
import io.netty.util.internal.logging.InternalLogger;
|
||||||
import io.netty.util.internal.logging.InternalLoggerFactory;
|
import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||||
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
@ -253,8 +253,8 @@ public class DnsNameResolverTest {
|
|||||||
group.shutdownGracefully();
|
group.shutdownGracefully();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@After
|
||||||
public void reset() {
|
public void reset() throws Exception {
|
||||||
resolver.clearCache();
|
resolver.clearCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user