Skip to content

Close idle transport connections when targets are drained or disposed#193

Open
AnyCPU wants to merge 1 commit intobasecamp:mainfrom
AnyCPU:fix/transport_idle_conn_presure_1
Open

Close idle transport connections when targets are drained or disposed#193
AnyCPU wants to merge 1 commit intobasecamp:mainfrom
AnyCPU:fix/transport_idle_conn_presure_1

Conversation

@AnyCPU
Copy link
Contributor

@AnyCPU AnyCPU commented Feb 16, 2026

Each Target creates its own http.Transport with MaxIdleConnsPerHost: 100. When a target is replaced during deploy or removed via RemoveService, its idle connections are never explicitly closed. They linger until Go's default idle timeout (~90s).

During rapid deploys, these accumulate unnecessarily.

There are two disposal paths, neither of which cleaned up transport connections:

  • Deploy (router.go:124-127, 153-156): Calls Dispose() then DrainAll() — in-flight requests are drained, but the transport's idle connection pool is never closed;
  • RemoveService (router.go:193): Calls only Dispose() — no drain, no transport cleanup at all.

Fix

  • Store the *http.Transport on the Target struct instead of creating it inline in the ReverseProxy;
  • Call transport.CloseIdleConnections() at the end of Target.Drain(), after all in-flight requests have completed or been cancelled;
  • Add TargetList.CloseIdleConnections() and call it from LoadBalancer.Dispose(), covering the RemoveService path where DrainAll is never called;
  • Both calls are safe and idempotent — CloseIdleConnections only affects idle connections, not active ones mid-RoundTrip.

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.

1 participant