-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Support PAC scripts that return multiple proxies #40082
Conversation
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs
Outdated
Show resolved
Hide resolved
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.
Did a first pass on this for style things.
Is this how other clients do it? Just want to make sure we're following precedent (or a spec if there happens to be one somewhere). |
src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinInetProxyHelper.cs
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/HttpRequestException.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/HttpRequestException.cs
Outdated
Show resolved
Hide resolved
We should ask the WinInet/WinHttp team about this. They can tell us the algorithm they use. |
src/System.Net.Http.WinHttpHandler/src/System/Net/Http/WinInetProxyHelper.cs
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
Outdated
Show resolved
Hide resolved
…ailed" case will recover quicker if another proxy starts working.
…-pac # Conflicts: # src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpWindowsProxy.cs
/azp run |
Azure Pipelines successfully started running 4 pipeline(s). |
@stephentoub @davidsh @dotnet/ncl ready for review, thanks. |
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/FailedProxyCollection.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/FailedProxyCollection.cs
Outdated
Show resolved
Hide resolved
src/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/MultiProxy.cs
Outdated
Show resolved
Hide resolved
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.
Left a comment about the use of the 'Collection' suffix for a class that isn't a .NET collection type.
Also, please run final Outerloop tests before merge. |
/azp run |
Azure Pipelines successfully started running 4 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 4 pipeline(s). |
/azp run |
Azure Pipelines successfully started running 4 pipeline(s). |
|
||
// This lock can be folded into _nextFlushTicks for space optimization, but | ||
// this class should only have a single instance so would rather have clarity. | ||
private SpinLock _flushLock = new SpinLock(); |
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.
@scalablecory, I only just noticed this. Why did you choose to use a spin lock here rather than a regular lock?
/// so it's only run periodically and is disabled until we exceed <see cref="LargeProxyConfigBoundary"/> failed proxies. | ||
/// </remarks> | ||
[MethodImpl(MethodImplOptions.NoInlining)] | ||
private void CleanupHelper() |
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.
Presumably we expect only a relatively small number of proxies to end up as failed? Instead of looping through, storing times, etc., did you consider instead just creating a timer that will remove the proxy from the dictionary when it fires? That seems like it'd be a lot simpler.
/// Cleans up any old proxies that should no longer be marked as failing. | ||
/// </summary> | ||
/// <remarks> | ||
/// I expect this to never be called by <see cref="Cleanup"/> in a production system. It is only needed in the case |
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.
Nit: I generally prefer code to not use "I". When I read this code in 6 months, or a year, or a few years, who is "I"... it means I need to go and figure out who the developer was who committed the code. I'd personally prefer it if it just said "We" or if it was written to avoid the need for a pronoun, e.g. "This code is unlikely to ever be called in a production system."
/// that a system has a very large number of proxies that the PAC script cycles through. It is moderately expensive, | ||
/// so it's only run periodically and is disabled until we exceed <see cref="LargeProxyConfigBoundary"/> failed proxies. | ||
/// </remarks> | ||
[MethodImpl(MethodImplOptions.NoInlining)] |
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.
This attribute should not be necessary. There's a lot of code here, such that the JIT wouldn't generally want to inline it, and even if those heuristics changed, it's got exception handling that would prevent it as well.
try | ||
{ | ||
_flushLock.TryEnter(ref lockTaken); | ||
if (!lockTaken) |
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.
Especially with this logic there's no reason to use a spin lock, as this code is saying to not spin/block at all. The code just use Monitor.TryEnter on this. I suspect you'll find SpinLock is more expensive given the ctor that was used to create it.
* Support PAC scripts that return multiple proxies. Resolves dotnet/corefx#39370 Commit migrated from dotnet/corefx@5e97c2b
This enables
SocketsHttpHandler
support for PAC scripts that return multiple eligible proxies for a single URL.If a single proxy is returned, the old proxy path is followed.
If multiple proxies are returned, they will be used for failover in left-to-right order. A request finally fails after it has tried each proxy.
When a proxy fails, it will be marked as a failed proxy for 30 minutes, which is what WinHTTP and Firefox do. If all proxies have failed, it will try using the proxy that would have its 30 minutes elapse the soonest.
Resolves #39370.