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

feat: Use SocketsHttpHandler to configure HttpClient in .NET 6+ #2931

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

tippmar-nr
Copy link
Member

@tippmar-nr tippmar-nr commented Dec 18, 2024

  • Updated NRHttpClient to dynamically create an instance of SocketsHttpHandler when the app is running in .NET 6 or later, and configured PooledConnectionTimeout and PooledConnectionIdleTimeout to help the agent respond better to DNS changes. The connection timeout value is hard-coded to 5 minutes, which overrides the default of "never" and is probably sufficient for our needs. I didn't see a compelling reason to add a configuration setting for this value. Resolves Update HttpClient usage to better support DNS changes on .NET/.NET Core #1845.

Additional refactoring:

  • Introduces a helper class (AsyncHelper) to safely execute async methods synchronously. Used in NRHttpClient.Send() as an attempt to avoid deadlocks in the (eventual) call to HttpClient.SendAsync(). Taken from https://stackoverflow.com/a/56928748/2078975 which seems to be modeled after https://learn.microsoft.com/en-us/archive/msdn-magazine/2015/july/async-programming-brownfield-async-development#the-thread-pool-hack.
  • Updated all event aggregators to log the ... harvest finished message even if no events were sent. This will help in troubleshooting recently reported deadlocks when sending data.
  • Renamed IHttpClientFactory.CreateClient() to GetOrCreateClient() to better reflect what the method does.
  • Removed an unused property from IHttpClient and the classes that implement it
  • Refactored ConnectionHandler.SendDataOverWire<T>() to make exception handling a bit cleaner and more clear.
  • Cleaned up several log messages in exception handlers so that they only log the exception message instead of the full stack trace if the handler is just going to throw the exception again anyway.
  • Added logging to allow better tracing when sending data.
  • Added a couple usings in NRHttpClient for objects that are IDisposable (HttpRequestMessage, ByteArrayContent)

@tippmar-nr tippmar-nr marked this pull request as ready for review December 19, 2024 17:36
@tippmar-nr tippmar-nr requested a review from a team as a code owner December 19, 2024 17:36
@codecov-commenter
Copy link

Codecov Report

Attention: Patch coverage is 90.15152% with 13 lines in your changes missing coverage. Please review.

Project coverage is 81.44%. Comparing base (63788ff) to head (5c4429d).
Report is 7 commits behind head on main.

Files with missing lines Patch % Lines
...ic/Agent/Core/DataTransport/Client/NRHttpClient.cs 71.87% 7 Missing and 2 partials ⚠️
...elic/Agent/Core/DataTransport/ConnectionHandler.cs 88.23% 1 Missing and 1 partial ⚠️
...Relic/Agent/Core/Aggregators/LogEventAggregator.cs 93.33% 0 Missing and 1 partial ⚠️
...nt/Core/DataTransport/Client/HttpContentWrapper.cs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2931      +/-   ##
==========================================
+ Coverage   81.42%   81.44%   +0.01%     
==========================================
  Files         465      465              
  Lines       29563    29603      +40     
  Branches     3278     3285       +7     
==========================================
+ Hits        24073    24110      +37     
- Misses       4697     4698       +1     
- Partials      793      795       +2     
Flag Coverage Δ
Agent 82.37% <90.15%> (+0.01%) ⬆️
Profiler 73.13% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/Agent/NewRelic/Agent/Core/Agent.cs 74.30% <ø> (ø)
...ic/Agent/Core/Aggregators/CustomEventAggregator.cs 98.71% <100.00%> (+0.03%) ⬆️
...lic/Agent/Core/Aggregators/ErrorEventAggregator.cs 94.89% <100.00%> (+0.10%) ⬆️
...lic/Agent/Core/Aggregators/ErrorTraceAggregator.cs 90.12% <100.00%> (+0.25%) ⬆️
...ewRelic/Agent/Core/Aggregators/MetricAggregator.cs 97.18% <100.00%> (+0.16%) ⬆️
...elic/Agent/Core/Aggregators/SpanEventAggregator.cs 82.41% <100.00%> (+0.39%) ⬆️
...Relic/Agent/Core/Aggregators/SqlTraceAggregator.cs 100.00% <100.00%> (ø)
...ent/Core/Aggregators/TransactionEventAggregator.cs 99.00% <100.00%> (+0.02%) ⬆️
...ent/Core/Aggregators/TransactionTraceAggregator.cs 94.20% <100.00%> (+0.35%) ⬆️
.../Agent/Core/DataTransport/Client/HttpClientBase.cs 84.09% <100.00%> (ø)
... and 13 more

/// <typeparam name="TReturn"></typeparam>
/// <param name="task"></param>
/// <returns></returns>
public static TReturn RunSync<TReturn>(Func<Task<TReturn>> task)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marty and I talked about removing this helper method.

@@ -65,7 +102,9 @@ public override IHttpResponse Send(IHttpRequest request)
req.Content.Headers.Add(contentHeader.Key, contentHeader.Value);
}

var response = _httpClientWrapper.SendAsync(req).GetAwaiter().GetResult();
Log.Finest($"Request({request.RequestGuid}: Sending");
var response = AsyncHelper.RunSync(() => _httpClientWrapper.SendAsync(req));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not need this helper method, because ConfigureAwait(false) seems to help resolve the same problem in a simpler manner.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update HttpClient usage to better support DNS changes on .NET/.NET Core
3 participants