Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented May 19, 2025

Issue

When PooledConnectionLifetime is set to TimeSpan.Zero, HTTP/2 keep-alive pings don't work, even if explicitly configured. This is because the connection pool manager optimization that avoids storing connections (when lifetime is zero) skips creating the heartbeat timer needed for ping functionality.

Root Cause

In HttpConnectionPoolManager.cs, there's this optimization condition:

bool avoidStoringConnections =
    settings._maxConnectionsPerServer == int.MaxValue &&
    (settings._pooledConnectionIdleTimeout == TimeSpan.Zero ||
     settings._pooledConnectionLifetime == TimeSpan.Zero);

When this condition is true, the code skips creating the heartbeat timer, regardless of whether the user has configured HTTP/2 keep-alive pings.

Fix

I've modified the condition to also consider whether keep-alive pings are enabled:

bool avoidStoringConnections =
    settings._maxConnectionsPerServer == int.MaxValue &&
    (settings._pooledConnectionIdleTimeout == TimeSpan.Zero ||
     settings._pooledConnectionLifetime == TimeSpan.Zero) &&
    settings._keepAlivePingDelay == Timeout.InfiniteTimeSpan;

This ensures that if pings are configured (keepAlivePingDelay is not InfiniteTimeSpan), connections will be stored and the heartbeat timer will be created, even if the connection lifetime is zero.

I've also added test cases to verify this fix:

  1. A test that confirms pings work when PooledConnectionLifetime = TimeSpan.Zero and ping settings are configured
  2. A test that confirms the default behavior (no pings) when ping settings aren't configured with zero lifetime

Fixes #113532.

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • dc.services.visualstudio.com
    • Triggering command: /home/REDACTED/work/runtime/runtime/.dotnet/dotnet msbuild /m /nologo /clp:Summary /v:minimal /nr:true /warnaserror /p:TreatWarningsAsErrors=true /p:ContinuousIntegrationBuild=false /home/REDACTED/work/runtime/runtime/artifacts/toolset/restore.proj /t:__WriteToolsetLocation /clp:ErrorsOnly;NoSummary /p:__ToolsetLocationOutputFile=/home/REDACTED/work/runtime/runtime/artifacts/toolset/10.0.0-beta.25260.104.txt (dns block)
  • pkgs.dev.azure.com
    • Triggering command: /home/REDACTED/work/runtime/runtime/.dotnet/dotnet msbuild /m /nologo /clp:Summary /v:minimal /nr:true /warnaserror /p:TreatWarningsAsErrors=true /p:ContinuousIntegrationBuild=false /home/REDACTED/work/runtime/runtime/artifacts/toolset/restore.proj /t:__WriteToolsetLocation /clp:ErrorsOnly;NoSummary /p:__ToolsetLocationOutputFile=/home/REDACTED/work/runtime/runtime/artifacts/toolset/10.0.0-beta.25260.104.txt (dns block)

If you need me to access, download, or install something from one of these locations, you can either:


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@dotnet-policy-service dotnet-policy-service bot added the linkable-framework Issues associated with delivering a linker friendly framework label May 19, 2025
@MihaZupan MihaZupan added area-System.Net.Http and removed linkable-framework Issues associated with delivering a linker friendly framework labels May 19, 2025
Copy link
Contributor

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

@Copilot Copilot AI changed the title [WIP] HTTP/2 pings don't work if the connection lifetime is zero Fix HTTP/2 pings not working with zero connection lifetime May 19, 2025
@Copilot Copilot AI requested a review from stephentoub May 19, 2025 18:21
Copilot finished work on behalf of stephentoub May 19, 2025 18:21
@stephentoub
Copy link
Member

The new test file will need to be added to the .csproj. Otherwise, it won't be included in the built tests.

Copy link
Contributor Author

Copilot AI commented May 19, 2025

The new test file will need to be added to the .csproj. Otherwise, it won't be included in the built tests.

I've added the test file to the System.Net.Http.Functional.Tests.csproj file so it will be included in the built tests (f1088d8).

@stephentoub
Copy link
Member

Please write the test(s) in the same style as the rest of the tests and include it or then in an existing test file rather than creating a new one.

Copy link
Contributor Author

Copilot AI commented Jun 7, 2025

Please write the test(s) in the same style as the rest of the tests and include it or then in an existing test file rather than creating a new one.

I've moved the test methods into the existing SocketsHttpHandlerTest.Http2KeepAlivePing.cs file and removed the separate test file as requested. The tests follow the same style and patterns as the existing tests in that file (2fc0eb7).

Warning

Firewall rules blocked me from connecting to one or more addresses

I tried to connect to the following addresses, but was blocked by firewall rules:

  • n3kvsblobprodcus335.vsblob.vsassets.io
    • Triggering command: /home/REDACTED/work/runtime/runtime/.dotnet/dotnet msbuild /m /nologo /clp:Summary /v:minimal /nr:true /warnaserror /p:TreatWarningsAsErrors=true /p:ContinuousIntegrationBuild=false /home/REDACTED/work/runtime/runtime/artifacts/toolset/restore.proj /t:__WriteToolsetLocation /clp:ErrorsOnly;NoSummary /p:__ToolsetLocationOutputFile=/home/REDACTED/work/runtime/runtime/artifacts/toolset/10.0.0-beta.25260.104.txt (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of stephentoub June 7, 2025 18:50
@stephentoub stephentoub marked this pull request as ready for review June 17, 2025 20:15
@Copilot Copilot AI review requested due to automatic review settings June 17, 2025 20:15
@stephentoub stephentoub enabled auto-merge (squash) June 17, 2025 20:16
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR ensures HTTP/2 keep-alive pings continue working when PooledConnectionLifetime is zero by adjusting the connection‐pool optimization and adding tests.

  • Update avoidStoringConnections to skip the optimization only when no pings are configured.
  • Enhance functional tests to cover infinite and zero connection lifetimes with ping enabled.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2KeepAlivePing.cs Parameterize the test with connectionLifetimeMilliseconds and set PooledConnectionLifetime accordingly
src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/HttpConnectionPoolManager.cs Extend the zero‐lifetime optimization to require KeepAlivePingDelay to be infinite before avoiding stored connections
Comments suppressed due to low confidence (1)

src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.Http2KeepAlivePing.cs:98

  • Add a test case for HttpKeepAlivePingPolicy.Always with connectionLifetimeMilliseconds = 0 (e.g. InlineData(HttpKeepAlivePingPolicy.Always, 0)) to verify pings are sent when lifetime is zero under the Always policy.
        [InlineData(HttpKeepAlivePingPolicy.Always, -1)]

@stephentoub
Copy link
Member

/ba-g infra failures

@stephentoub stephentoub merged commit 3c5f74a into main Jun 18, 2025
79 of 86 checks passed
@stephentoub stephentoub deleted the copilot/fix-113532 branch June 18, 2025 01:21
@github-actions github-actions bot locked and limited conversation to collaborators Jul 18, 2025
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.

HTTP/2 pings don't work if the connection lifetime is zero
3 participants