Skip to content

Commit 60e0272

Browse files
committed
NameResolver API should be non blocking, close AsyncHttpClient#1034
1 parent 48edae4 commit 60e0272

23 files changed

+581
-235
lines changed

client/src/main/java/org/asynchttpclient/DefaultRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
import java.util.List;
2727
import java.util.Map;
2828

29-
import org.asynchttpclient.channel.NameResolver;
3029
import org.asynchttpclient.channel.pool.ConnectionPoolPartitioning;
3130
import org.asynchttpclient.cookie.Cookie;
3231
import org.asynchttpclient.proxy.ProxyServer;
3332
import org.asynchttpclient.request.body.generator.BodyGenerator;
3433
import org.asynchttpclient.request.body.multipart.Part;
34+
import org.asynchttpclient.resolver.NameResolver;
3535
import org.asynchttpclient.uri.Uri;
3636

3737
public class DefaultRequest implements Request {

client/src/main/java/org/asynchttpclient/Request.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
import java.util.Collection;
2727
import java.util.List;
2828

29-
import org.asynchttpclient.channel.NameResolver;
3029
import org.asynchttpclient.channel.pool.ConnectionPoolPartitioning;
3130
import org.asynchttpclient.cookie.Cookie;
3231
import org.asynchttpclient.proxy.ProxyServer;
3332
import org.asynchttpclient.request.body.generator.BodyGenerator;
3433
import org.asynchttpclient.request.body.multipart.Part;
34+
import org.asynchttpclient.resolver.NameResolver;
3535
import org.asynchttpclient.uri.Uri;
3636

3737
/**

client/src/main/java/org/asynchttpclient/RequestBuilderBase.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@
3131
import java.util.List;
3232
import java.util.Map;
3333

34-
import org.asynchttpclient.channel.NameResolver;
3534
import org.asynchttpclient.channel.pool.ConnectionPoolPartitioning;
3635
import org.asynchttpclient.cookie.Cookie;
3736
import org.asynchttpclient.proxy.ProxyServer;
3837
import org.asynchttpclient.request.body.generator.BodyGenerator;
3938
import org.asynchttpclient.request.body.generator.ReactiveStreamsBodyGenerator;
4039
import org.asynchttpclient.request.body.multipart.Part;
40+
import org.asynchttpclient.resolver.JdkNameResolver;
41+
import org.asynchttpclient.resolver.NameResolver;
4142
import org.asynchttpclient.uri.Uri;
4243
import org.asynchttpclient.util.UriEncoder;
4344
import org.reactivestreams.Publisher;
@@ -85,7 +86,7 @@ public abstract class RequestBuilderBase<T extends RequestBuilderBase<T>> {
8586
protected long rangeOffset;
8687
protected Charset charset;
8788
protected ConnectionPoolPartitioning connectionPoolPartitioning = ConnectionPoolPartitioning.PerHostConnectionPoolPartitioning.INSTANCE;
88-
protected NameResolver nameResolver = NameResolver.JdkNameResolver.INSTANCE;
89+
protected NameResolver nameResolver = JdkNameResolver.INSTANCE;
8990

9091
protected RequestBuilderBase(String method, boolean disableUrlEncoding) {
9192
this.method = method;
Lines changed: 65 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010-2012 Sonatype, Inc. All rights reserved.
2+
* Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
33
*
44
* This program is licensed to you under the Apache License Version 2.0,
55
* and you may not use this file except in compliance with the Apache License Version 2.0.
@@ -14,57 +14,100 @@
1414

1515
import io.netty.channel.Channel;
1616

17-
import java.net.InetAddress;
17+
import java.net.InetSocketAddress;
18+
import java.util.List;
1819

1920
import org.asynchttpclient.AsyncHandler;
20-
import org.asynchttpclient.channel.NameResolution;
2121
import org.asynchttpclient.netty.request.NettyRequest;
2222

2323
/**
2424
* This interface hosts new low level callback methods on {@link AsyncHandler}.
25-
* For now, those methods are in a dedicated interface in order not to break the
26-
* existing API, but could be merged into one of the existing ones in AHC 2.
2725
*
2826
*/
2927
public interface AsyncHandlerExtensions {
3028

29+
// ////////// DNS /////////////////
30+
3131
/**
32-
* Notify the callback when trying to open a new connection.
32+
* Notify the callback before DNS resolution
33+
*
34+
* @param name the name to be resolved
3335
*/
34-
void onConnectionOpen();
36+
void onDnsResolution(String name);
3537

3638
/**
37-
* Notify the callback after DNS resolution has completed.
39+
* Notify the callback after DNS resolution was successful.
3840
*
41+
* @param name the name to be resolved
3942
* @param addresses the resolved addresses
4043
*/
41-
void onDnsResolved(NameResolution[] addresses);
44+
void onDnsResolutionSuccess(String name, List<InetSocketAddress> addresses);
45+
46+
/**
47+
* Notify the callback after DNS resolution failed.
48+
*
49+
* @param name the name to be resolved
50+
* @param cause the failure cause
51+
*/
52+
void onDnsResolutionFailure(String name, Throwable cause);
53+
54+
// ////////////// TCP CONNECT ////////
55+
56+
/**
57+
* Notify the callback when trying to open a new connection.
58+
*
59+
* Might be called several times if the name was resolved to multiple addresses and we failed to connect to the first(s) one(s).
60+
*
61+
* @param address the address we try to connect to
62+
*/
63+
void onTcpConnect(InetSocketAddress address);
4264

4365
/**
4466
* Notify the callback after a successful connect
4567
*
68+
* @param address the address we try to connect to
4669
* @param connection the connection
47-
* @param address the connected addresses
4870
*/
49-
void onConnectionSuccess(Channel connection, InetAddress address);
50-
71+
void onTcpConnectSuccess(InetSocketAddress remoteAddress, Channel connection);
72+
5173
/**
5274
* Notify the callback after a failed connect.
53-
* Might be called several times, or be followed by onConnectionSuccess
54-
* when the name was resolved to multiple addresses.
5575
*
56-
* @param address the tentative addresses
76+
* Might be called several times, or be followed by onTcpConnectSuccess when the name was resolved to multiple addresses.
77+
*
78+
* @param address the address we try to connect to
79+
* @param cause the cause of the failure
5780
*/
58-
void onConnectionFailure(InetAddress address);
81+
void onTcpConnectFailure(InetSocketAddress remoteAddress, Throwable cause);
82+
83+
// ////////////// TLS ///////////////
84+
85+
/**
86+
* Notify the callback before TLS handshake
87+
*/
88+
void onTlsHandshake();
89+
90+
/**
91+
* Notify the callback after the TLS was successful
92+
*/
93+
void onTlsHandshakeSuccess();
94+
95+
/**
96+
* Notify the callback after the TLS failed
97+
*
98+
* @param cause the cause of the failure
99+
*/
100+
void onTlsHandshakeFailure(Throwable cause);
101+
102+
// /////////// POOLING /////////////
59103

60104
/**
61105
* Notify the callback when trying to fetch a connection from the pool.
62106
*/
63107
void onConnectionPool();
64108

65109
/**
66-
* Notify the callback when a new connection was successfully fetched from
67-
* the pool.
110+
* Notify the callback when a new connection was successfully fetched from the pool.
68111
*
69112
* @param connection the connection
70113
*/
@@ -77,10 +120,11 @@ public interface AsyncHandlerExtensions {
77120
*/
78121
void onConnectionOffer(Channel connection);
79122

123+
// //////////// SENDING //////////////
124+
80125
/**
81-
* Notify the callback when a request is being written on the wire. If the
82-
* original request causes multiple requests to be sent, for example,
83-
* because of authorization or retry, it will be notified multiple times.
126+
* Notify the callback when a request is being written on the channel. If the original request causes multiple requests to be sent, for example, because of authorization or
127+
* retry, it will be notified multiple times.
84128
*
85129
* @param request the real request object as passed to the provider
86130
*/
@@ -90,10 +134,4 @@ public interface AsyncHandlerExtensions {
90134
* Notify the callback every time a request is being retried.
91135
*/
92136
void onRetry();
93-
94-
/**
95-
* Notify the callback when the SSL handshake performed to establish an
96-
* HTTPS connection has been completed.
97-
*/
98-
void onSslHandshakeCompleted();
99137
}

client/src/main/java/org/asynchttpclient/channel/NameResolution.java renamed to client/src/main/java/org/asynchttpclient/handler/AsyncHandlerExtensionsUtils.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,16 @@
1010
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1111
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
1212
*/
13-
package org.asynchttpclient.channel;
13+
package org.asynchttpclient.handler;
1414

15-
import java.net.InetAddress;
15+
import org.asynchttpclient.AsyncHandler;
1616

17-
public class NameResolution {
17+
public final class AsyncHandlerExtensionsUtils {
1818

19-
public static final long UNKNOWN_EXPIRATION = 0;
20-
21-
public final InetAddress address;
22-
public final long expiration;
23-
24-
public NameResolution(InetAddress address) {
25-
this(address, UNKNOWN_EXPIRATION);
26-
}
27-
28-
public NameResolution(InetAddress address, long expiration) {
29-
this.address = address;
30-
this.expiration = expiration;
19+
public static AsyncHandlerExtensions toAsyncHandlerExtensions(AsyncHandler<?> asyncHandler) {
20+
return asyncHandler instanceof AsyncHandlerExtensions ? (AsyncHandlerExtensions) asyncHandler : null;
21+
}
22+
23+
private AsyncHandlerExtensionsUtils() {
3124
}
3225
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright (c) 2015 AsyncHttpClient Project. All rights reserved.
3+
*
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at
7+
* http://www.apache.org/licenses/LICENSE-2.0.
8+
*
9+
* Unless required by applicable law or agreed to in writing,
10+
* software distributed under the Apache License Version 2.0 is distributed on an
11+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
13+
*/
14+
package org.asynchttpclient.handler;
15+
16+
import io.netty.channel.Channel;
17+
18+
import java.net.InetSocketAddress;
19+
import java.util.List;
20+
21+
import org.asynchttpclient.AsyncHandler;
22+
import org.asynchttpclient.netty.request.NettyRequest;
23+
24+
public abstract class ExtendedAsyncHandler<T> implements AsyncHandler<T>, AsyncHandlerExtensions {
25+
26+
@Override
27+
public void onDnsResolution(String name) {
28+
}
29+
30+
@Override
31+
public void onDnsResolutionSuccess(String name, List<InetSocketAddress> addresses) {
32+
}
33+
34+
@Override
35+
public void onDnsResolutionFailure(String name, Throwable cause) {
36+
}
37+
38+
@Override
39+
public void onTcpConnect(InetSocketAddress address) {
40+
}
41+
42+
@Override
43+
public void onTcpConnectSuccess(InetSocketAddress remoteAddress, Channel connection) {
44+
}
45+
46+
@Override
47+
public void onTcpConnectFailure(InetSocketAddress remoteAddress, Throwable cause) {
48+
}
49+
50+
@Override
51+
public void onTlsHandshake() {
52+
}
53+
54+
@Override
55+
public void onTlsHandshakeSuccess() {
56+
}
57+
58+
@Override
59+
public void onTlsHandshakeFailure(Throwable cause) {
60+
}
61+
62+
@Override
63+
public void onConnectionPool() {
64+
}
65+
66+
@Override
67+
public void onConnectionPooled(Channel connection) {
68+
}
69+
70+
@Override
71+
public void onConnectionOffer(Channel connection) {
72+
}
73+
74+
@Override
75+
public void onRequestSend(NettyRequest request) {
76+
}
77+
78+
@Override
79+
public void onRetry() {
80+
}
81+
}

client/src/main/java/org/asynchttpclient/handler/MaxRedirectException.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
/*
2-
* Copyright 2010 Ning, Inc.
2+
* Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
33
*
4-
* Ning licenses this file to you under the Apache License, version 2.0
5-
* (the "License"); you may not use this file except in compliance with the
6-
* License. You may obtain a copy of the License at:
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13-
* License for the specific language governing permissions and limitations
14-
* under the License.
4+
* This program is licensed to you under the Apache License Version 2.0,
5+
* and you may not use this file except in compliance with the Apache License Version 2.0.
6+
* You may obtain a copy of the Apache License Version 2.0 at
7+
* http://www.apache.org/licenses/LICENSE-2.0.
158
*
9+
* Unless required by applicable law or agreed to in writing,
10+
* software distributed under the Apache License Version 2.0 is distributed on an
11+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
1613
*/
1714
package org.asynchttpclient.handler;
1815

client/src/main/java/org/asynchttpclient/netty/NettyResponseFuture.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
package org.asynchttpclient.netty;
1515

1616
import static org.asynchttpclient.util.DateUtils.millisTime;
17+
import static org.asynchttpclient.util.MiscUtils.getCause;
1718
import io.netty.channel.Channel;
1819
import io.netty.handler.codec.http.HttpHeaders;
1920

@@ -212,8 +213,7 @@ public final void done() {
212213
} catch (ExecutionException t) {
213214
return;
214215
} catch (RuntimeException t) {
215-
Throwable exception = t.getCause() != null ? t.getCause() : t;
216-
exEx.compareAndSet(null, new ExecutionException(exception));
216+
exEx.compareAndSet(null, new ExecutionException(getCause(t)));
217217

218218
} finally {
219219
latch.countDown();
@@ -267,7 +267,7 @@ public void execute(Runnable command) {
267267

268268
return completable;
269269
}
270-
270+
271271
// INTERNAL
272272

273273
public Uri getUri() {
@@ -296,7 +296,7 @@ public void cancelTimeouts() {
296296
public final Request getTargetRequest() {
297297
return targetRequest;
298298
}
299-
299+
300300
public final Request getCurrentRequest() {
301301
return currentRequest;
302302
}
@@ -433,14 +433,13 @@ public void setCurrentRequest(Request currentRequest) {
433433
}
434434

435435
/**
436-
* Return true if the {@link Future} can be recovered. There is some scenario where a connection can be closed by an
437-
* unexpected IOException, and in some situation we can recover from that exception.
436+
* Return true if the {@link Future} can be recovered. There is some scenario where a connection can be closed by an unexpected IOException, and in some situation we can
437+
* recover from that exception.
438438
*
439439
* @return true if that {@link Future} cannot be recovered.
440440
*/
441441
public boolean canBeReplayed() {
442-
return !isDone() && canRetry()
443-
&& !(Channels.isChannelValid(channel) && !getUri().getScheme().equalsIgnoreCase("https")) && !inAuth.get() && !inProxyAuth.get();
442+
return !isDone() && canRetry() && !(Channels.isChannelValid(channel) && !getUri().getScheme().equalsIgnoreCase("https")) && !inAuth.get() && !inProxyAuth.get();
444443
}
445444

446445
public long getStart() {

0 commit comments

Comments
 (0)