-
Notifications
You must be signed in to change notification settings - Fork 926
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Respect TTL of a DNS record for proxy config #5960
base: main
Are you sure you want to change the base?
Changes from 7 commits
417bf3b
3681f0f
f57259c
f40cbe4
a26e3f5
649469e
ab43277
a6e725c
e0819c4
0b3cc2b
54ec6f3
a67ee3f
241b4ff
fce4fd2
7d85a69
67f4997
e775351
18b24ea
979e6fd
3dbc847
fcfed45
09efa86
25ff1af
43212b6
195033f
d1c9596
d5c8326
1240a24
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,9 @@ | |
import java.net.InetSocketAddress; | ||
import java.util.function.BiConsumer; | ||
|
||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import com.linecorp.armeria.client.HttpChannelPool.PoolKey; | ||
import com.linecorp.armeria.client.endpoint.EmptyEndpointGroupException; | ||
import com.linecorp.armeria.client.proxy.HAProxyConfig; | ||
|
@@ -50,6 +53,7 @@ | |
|
||
final class HttpClientDelegate implements HttpClient { | ||
|
||
private static final Logger logger = LoggerFactory.getLogger(HttpClientDelegate.class); | ||
private final HttpClientFactory factory; | ||
private final AddressResolverGroup<InetSocketAddress> addressResolverGroup; | ||
|
||
|
@@ -90,7 +94,7 @@ public HttpResponse execute(ClientRequestContext ctx, HttpRequest req) throws Ex | |
final SessionProtocol protocol = ctx.sessionProtocol(); | ||
final ProxyConfig proxyConfig; | ||
try { | ||
proxyConfig = getProxyConfig(protocol, endpoint); | ||
proxyConfig = getProxyConfig(protocol, endpoint, ctx); | ||
} catch (Throwable t) { | ||
return earlyFailedResponse(t, ctx); | ||
} | ||
|
@@ -215,10 +219,34 @@ private void acquireConnectionAndExecute0(ClientRequestContext ctx, Endpoint end | |
} | ||
} | ||
|
||
private ProxyConfig getProxyConfig(SessionProtocol protocol, Endpoint endpoint) { | ||
private ProxyConfig getProxyConfig(SessionProtocol protocol, Endpoint endpoint, ClientRequestContext ctx) { | ||
final ProxyConfig proxyConfig = factory.proxyConfigSelector().select(protocol, endpoint); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be efficient if we could skip the resolution process if |
||
requireNonNull(proxyConfig, "proxyConfig"); | ||
|
||
// DirectProxyConfig does not have proxyAddress as its field. | ||
if (proxyConfig.proxyAddress() != null) { | ||
ikhoon marked this conversation as resolved.
Show resolved
Hide resolved
|
||
final Future<InetSocketAddress> resolveFuture = addressResolverGroup.getResolver( | ||
ctx.eventLoop().withoutContext()).resolve(proxyConfig.proxyAddress()); | ||
|
||
resolveFuture.addListener(future -> { | ||
if (future.isSuccess()) { | ||
final InetSocketAddress resolvedAddress = (InetSocketAddress) future.get(); | ||
if (resolvedAddress != null && !resolvedAddress.isUnresolved()) { | ||
proxyConfig.refreshDns(resolvedAddress); | ||
} else { | ||
logger.warn("Resolved address is invalid or unresolved: {}. " + | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't understand this case - are you concerned that the resolution succeeds but the Would it make sense to just align error handling with dns resolution for the normal code path (not using proxy)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for your comments! |
||
"Using previous address instead.", resolvedAddress); | ||
} | ||
} else { | ||
final Throwable cause = future.cause(); | ||
logger.warn("Failed to refresh {}'s ip address. " + | ||
"Use the previous inet address instead. reason: {}", | ||
proxyConfig.proxyAddress(), | ||
cause != null ? cause.getMessage() : "Unknown Error"); | ||
} | ||
}); | ||
} | ||
|
||
// special behavior for haproxy when sourceAddress is null | ||
if (proxyConfig.proxyType() == ProxyType.HAPROXY && | ||
((HAProxyConfig) proxyConfig).sourceAddress() == null) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have to recreate
ProxyConfig
with the new proxy address because the address is resolved:Because getting the
ProxyConfig
is now asynchronous, we have to change the signature of this method.We have two options:
CompletableFuture<ProxyConfig>
instead ofProxyConfig
Please let me know if you need further information. 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@minwoox , Thanks for your comments 🙇♂️
I made a new commit with following second option!
Because
ProxyConfig
will be resolved in other thread, so the methodmaybeHAProxy()
will getcapturedProxyAddress
instead ofServiceRequestContext
.Also,
res
instance will be returned right away even if future don't completed.So I used the method
earlyFailed(...)
instead ofearlyfailedResponse(...)
.When you have time, Please take another look 🙇♂️