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

Excessive "HttpMessageHandler cleanup cycle" Logs in Long-Running Service Injecting ISendGridClient #1213

Open
sdepouw opened this issue Sep 13, 2024 · 0 comments

Comments

@sdepouw
Copy link

sdepouw commented Sep 13, 2024

I have a Windows Service written in .NET 8 that uses C# classes, some of which use Dependency Injection (the AddSendGrid() extension) to get an instance of ISendGridClient. It seems that when using this in a Windows service, or otherwise a C# class that's loaded once and remains active for the entire application's runtime (basically think of it being used in a Singleton), our application logs are flooded with messages like this (note InjectableSendGridClient:

[07:14:06 DBG] Hosting started
[07:16:06 DBG] HttpMessageHandler expired after 120000ms for client 'InjectableSendGridClient'
[07:16:16 DBG] Starting HttpMessageHandler cleanup cycle with 1 items
[07:16:16 DBG] Ending HttpMessageHandler cleanup cycle after 0.0233ms - processed: 0 items - remaining: 1 items
[07:16:26 DBG] Starting HttpMessageHandler cleanup cycle with 1 items
[07:16:26 DBG] Ending HttpMessageHandler cleanup cycle after 0.0061ms - processed: 0 items - remaining: 1 items
[07:16:36 DBG] Starting HttpMessageHandler cleanup cycle with 1 items
[07:16:36 DBG] Ending HttpMessageHandler cleanup cycle after 0.0032ms - processed: 0 items - remaining: 1 items
[07:16:46 DBG] Starting HttpMessageHandler cleanup cycle with 1 items
[07:16:46 DBG] Ending HttpMessageHandler cleanup cycle after 0.0035ms - processed: 0 items - remaining: 1 items
[07:16:56 DBG] Starting HttpMessageHandler cleanup cycle with 1 items
[07:16:56 DBG] Ending HttpMessageHandler cleanup cycle after 0.0034ms - processed: 0 items - remaining: 1 items
[07:17:06 DBG] Starting HttpMessageHandler cleanup cycle with 1 items
[07:17:06 DBG] Ending HttpMessageHandler cleanup cycle after 0.006ms - processed: 0 items - remaining: 1 items
[07:17:16 DBG] Starting HttpMessageHandler cleanup cycle with 1 items

As you can see, after the given class is alive for 2 minutes, the cleanup cycle runs every 10 seconds after the fact. It appears that ISendGridClient is keeping a single HttpClient instance alive for the entire duration the ISendGridClient remains in scope.

Is there a way to use ISendGridClient in a disposable context? Something like using(ISendGridClient client = someFactory.CreateClient())? Or, would it be possible that, when injecting ISendGridClient via dependency injection (i.e. constructor injection) for it to manage its internal client so it isn't "kept alive" for long-running services/processes? Some way to support using ISendGridClient in singleton/long-running scenarios?

Note that I cannot simply "turn off logging at the Debug level" in this scenario.

Here's how we're setting up dependency injection in Program.cs:

using Microsoft.Extensions.Hosting;
using SendGrid.Extensions.DependencyInjection;

HostApplicationBuilder builder = Host.CreateApplicationBuilder();

builder.Services.AddSendGrid(opts => opts.ApiKey = "my-api-key");

Here's how we're using the class:

using SendGrid;

public class SendGridEmailService(ILogger<SendGridEmailService> logger, ISendGridClient client)
{
  // ISendGridClient used in this class
}

Current Workaround

Presently my only idea is to inject IServiceProvider instead, then get the client at runtime.

public class SendGridEmailSErvice(ILogger<SendGridEmailService> logger, ISerivceProvider provider)
{
  public async Task SendMailAsync(SendGridMessage message, CancellationToken cancellationToken)
  {
    ISendGridClient sendGridClient = provider.GetRequiredService<ISendGridClient>();
    await sendGridClient.SendEmailAsync(message, cancellationToken);
  }
}
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

No branches or pull requests

1 participant