DnsAddressResolverGroup should respect configured EventLoop (#10479)
Motivation: DnsAddressResolverGroup allows to be constructed with a DnsNameResolverBuilder and so should respect its configured EventLoop. Modifications: - Correctly respect the configured EventLoop - Ensure there are no thread-issues by calling copy() - Add unit tests Result: Fixes https://github.com/netty/netty/issues/10460
This commit is contained in:
parent
03b6be774d
commit
cc33da49aa
@ -50,14 +50,14 @@ public class DnsAddressResolverGroup extends AddressResolverGroup<InetSocketAddr
|
||||
public DnsAddressResolverGroup(
|
||||
Class<? extends DatagramChannel> channelType,
|
||||
DnsServerAddressStreamProvider nameServerProvider) {
|
||||
this(new DnsNameResolverBuilder());
|
||||
this.dnsResolverBuilder = new DnsNameResolverBuilder();
|
||||
dnsResolverBuilder.channelType(channelType).nameServerProvider(nameServerProvider);
|
||||
}
|
||||
|
||||
public DnsAddressResolverGroup(
|
||||
ChannelFactory<? extends DatagramChannel> channelFactory,
|
||||
DnsServerAddressStreamProvider nameServerProvider) {
|
||||
this(new DnsNameResolverBuilder());
|
||||
this.dnsResolverBuilder = new DnsNameResolverBuilder();
|
||||
dnsResolverBuilder.channelFactory(channelFactory).nameServerProvider(nameServerProvider);
|
||||
}
|
||||
|
||||
@ -72,7 +72,8 @@ public class DnsAddressResolverGroup extends AddressResolverGroup<InetSocketAddr
|
||||
|
||||
// we don't really need to pass channelFactory and nameServerProvider separately,
|
||||
// but still keep this to ensure backward compatibility with (potentially) override methods
|
||||
return newResolver((EventLoop) executor,
|
||||
EventLoop loop = dnsResolverBuilder.eventLoop;
|
||||
return newResolver(loop == null ? (EventLoop) executor : loop,
|
||||
dnsResolverBuilder.channelFactory(),
|
||||
dnsResolverBuilder.nameServerProvider());
|
||||
}
|
||||
@ -102,9 +103,11 @@ public class DnsAddressResolverGroup extends AddressResolverGroup<InetSocketAddr
|
||||
ChannelFactory<? extends DatagramChannel> channelFactory,
|
||||
DnsServerAddressStreamProvider nameServerProvider)
|
||||
throws Exception {
|
||||
DnsNameResolverBuilder builder = dnsResolverBuilder.copy();
|
||||
|
||||
// once again, channelFactory and nameServerProvider are most probably set in builder already,
|
||||
// but I do reassign them again to avoid corner cases with override methods
|
||||
return dnsResolverBuilder.eventLoop(eventLoop)
|
||||
return builder.eventLoop(eventLoop)
|
||||
.channelFactory(channelFactory)
|
||||
.nameServerProvider(nameServerProvider)
|
||||
.build();
|
||||
|
@ -36,7 +36,7 @@ import static java.util.Objects.requireNonNull;
|
||||
* A {@link DnsNameResolver} builder.
|
||||
*/
|
||||
public final class DnsNameResolverBuilder {
|
||||
private EventLoop eventLoop;
|
||||
volatile EventLoop eventLoop;
|
||||
private ChannelFactory<? extends DatagramChannel> channelFactory;
|
||||
private ChannelFactory<? extends SocketChannel> socketChannelFactory;
|
||||
private DnsCache resolveCache;
|
||||
|
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2020 The Netty Project
|
||||
*
|
||||
* The Netty Project 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 io.netty.resolver.dns;
|
||||
|
||||
import io.netty.channel.EventLoop;
|
||||
import io.netty.channel.MultithreadEventLoopGroup;
|
||||
import io.netty.channel.local.LocalHandler;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioDatagramChannel;
|
||||
import io.netty.resolver.AddressResolver;
|
||||
import io.netty.util.concurrent.Future;
|
||||
import io.netty.util.concurrent.FutureListener;
|
||||
import io.netty.util.concurrent.Promise;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.channels.UnsupportedAddressTypeException;
|
||||
|
||||
public class DnsAddressResolverGroupTest {
|
||||
@Test
|
||||
public void testUseConfiguredEventLoop() throws InterruptedException {
|
||||
NioEventLoopGroup group = new NioEventLoopGroup(1);
|
||||
final EventLoop loop = group.next();
|
||||
MultithreadEventLoopGroup defaultEventLoopGroup = new MultithreadEventLoopGroup(1, LocalHandler.newFactory());
|
||||
DnsNameResolverBuilder builder = new DnsNameResolverBuilder()
|
||||
.eventLoop(loop).channelType(NioDatagramChannel.class);
|
||||
DnsAddressResolverGroup resolverGroup = new DnsAddressResolverGroup(builder);
|
||||
try {
|
||||
final Promise<?> promise = loop.newPromise();
|
||||
AddressResolver<?> resolver = resolverGroup.getResolver(defaultEventLoopGroup.next());
|
||||
resolver.resolve(new SocketAddress() {
|
||||
private static final long serialVersionUID = 3169703458729818468L;
|
||||
}).addListener(new FutureListener<Object>() {
|
||||
@Override
|
||||
public void operationComplete(Future<Object> future) {
|
||||
try {
|
||||
Assert.assertThat(future.cause(), Matchers.instanceOf(UnsupportedAddressTypeException.class));
|
||||
Assert.assertTrue(loop.inEventLoop());
|
||||
promise.setSuccess(null);
|
||||
} catch (Throwable cause) {
|
||||
promise.setFailure(cause);
|
||||
}
|
||||
}
|
||||
}).await();
|
||||
promise.sync();
|
||||
} finally {
|
||||
resolverGroup.close();
|
||||
group.shutdownGracefully();
|
||||
defaultEventLoopGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user