Skip to content
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

Serialize Dns async-over-sync requests for the same host #49171

Merged
merged 2 commits into from
Mar 5, 2021

Conversation

stephentoub
Copy link
Member

@ghost
Copy link

ghost commented Mar 4, 2021

Tagging subscribers to this area: @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #48566
cc: @geoffkizer, @davidfowl

Author: stephentoub
Assignees: -
Labels:

area-System.Net

Milestone: -

@davidfowl
Copy link
Member

@sebastienros I think we should do proxy test run here (httpclient and YARP).

@geoffkizer
Copy link
Contributor

Could the code here be simplified using a semaphore per hostname?

@stephentoub
Copy link
Member Author

That's basically what this is: "waiting on the semaphore" is done by waiting on the task currently holding the baton.

If you mean actually having a SemaphoreSlim, for example, when is it removed from the dictionary to avoid a potential leak?

@geoffkizer
Copy link
Contributor

If you mean actually having a SemaphoreSlim,

Yeah, that's what I meant.

when is it removed from the dictionary to avoid a potential leak?

Ref count it under the lock.

@stephentoub
Copy link
Member Author

Ref count it under the lock.

How does that look different from what I have here? At that point, you're retrieving a semaphore instead of a task from the dictionary, and waiting on semaphore.WaitAsync instead of task, but then also needing to call semaphore.Release()?

@geoffkizer
Copy link
Contributor

How does that look different from what I have here?

It's probably not all that different; it mainly avoids using stuff like ContinueWith. For me, at least, I find it much easier to reason about simple awaits than to reason about ContinueWith, especially when you add stuff like TaskContinuationOptions.ExecuteSynchronously. I've gotten burned here in the past, so now my instinct is to try to avoid doing this if I can.

But it's not a big deal either way.

@stephentoub
Copy link
Member Author

It doesn't really avoid it :) In order to be able to support the task getting canceled, you need to be able to do work after the task completes rather than as part of the task. That means either ContinueWith or a separate async method in which we await. I chose the former. If you would strongly prefer it, I can switch to await; I chose ContinueWith because the common case is that cancellation doesn't happen, and with ContinueWith, I can specify OnlyOnCanceled and avoid the continuation in the common case.

@geoffkizer
Copy link
Contributor

It doesn't really avoid it :) In order to be able to support the task getting canceled, you need to be able to do work after the task completes rather than as part of the task. That means either ContinueWith or a separate async method in which we await. I chose the former. If you would strongly prefer it, I can switch to await; I chose ContinueWith because the common case is that cancellation doesn't happen, and with ContinueWith, I can specify OnlyOnCanceled and avoid the continuation in the common case.

Yeah, I understand. And this just makes me wish we optimized async methods better, so we wouldn't have to face that dilemma. But we're not going to fix that today :)

I'm happy with the code as it is.

@davidfowl
Copy link
Member

The only person I accept using ContinueWith is @stephentoub. I've stopped using it myself though 😆

@stephentoub stephentoub merged commit 69f5fdf into dotnet:main Mar 5, 2021
@stephentoub stephentoub deleted the coalescedns2 branch March 5, 2021 21:15
@ghost ghost locked as resolved and limited conversation to collaborators Apr 4, 2021
@karelz karelz added this to the 6.0.0 milestone May 20, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reduce the impact of blocking DNS calls on Unix
6 participants