perf: use named HttpClient with SocketsHttpHandler connection pooling for Jellyfin backend

This commit is contained in:
2026-04-05 11:44:03 -04:00
parent 8239316019
commit b1808bd60c
2 changed files with 28 additions and 1 deletions
+19
View File
@@ -176,6 +176,25 @@ builder.Services.ConfigureAll<HttpClientFactoryOptions>(options =>
// but we want to reduce noise in production logs
options.SuppressHandlerScope = true;
});
// Register a dedicated named HttpClient for Jellyfin backend with connection pooling.
// SocketsHttpHandler reuses TCP connections across the scoped JellyfinProxyService
// instances, eliminating per-request TCP/TLS handshake overhead.
builder.Services.AddHttpClient(JellyfinProxyService.HttpClientName)
.ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
{
// Keep up to 20 idle connections to Jellyfin alive at any time
MaxConnectionsPerServer = 20,
// Recycle pooled connections every 5 minutes to pick up DNS changes
PooledConnectionLifetime = TimeSpan.FromMinutes(5),
// Close idle connections after 90 seconds to avoid stale sockets
PooledConnectionIdleTimeout = TimeSpan.FromSeconds(90),
// Allow HTTP/2 multiplexing when Jellyfin supports it
EnableMultipleHttp2Connections = true,
// Follow redirects within Jellyfin
AllowAutoRedirect = true,
MaxAutomaticRedirections = 5
});
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
builder.Services.AddHttpContextAccessor();
@@ -10,9 +10,17 @@ namespace allstarr.Services.Jellyfin;
/// <summary>
/// Handles proxying requests to the Jellyfin server and authentication.
/// Uses a named HttpClient ("JellyfinBackend") with SocketsHttpHandler for
/// TCP connection pooling across scoped instances.
/// </summary>
public class JellyfinProxyService
{
/// <summary>
/// The IHttpClientFactory registration name for the Jellyfin backend client.
/// Configured with SocketsHttpHandler for connection pooling in Program.cs.
/// </summary>
public const string HttpClientName = "JellyfinBackend";
private readonly HttpClient _httpClient;
private readonly JellyfinSettings _settings;
private readonly IHttpContextAccessor _httpContextAccessor;
@@ -31,7 +39,7 @@ public class JellyfinProxyService
ILogger<JellyfinProxyService> logger,
RedisCacheService cache)
{
_httpClient = httpClientFactory.CreateClient();
_httpClient = httpClientFactory.CreateClient(HttpClientName);
_settings = settings.Value;
_httpContextAccessor = httpContextAccessor;
_logger = logger;