fix(overlay): reuse shared http.Transport to stop idle conn goroutine leak
송인서 committed
May 1, 2026 at 12:06 UTC
e2a1c7f64b55bc867fb8257c5a7025bbb838ad14
1 file changed
+27
-14
portal/overlay/overlay.go
+27
-14
@@ -66,10 +66,12 @@ func NormalizeConfig(cfg Config) (Config, error) {
66
}
67
68
type Overlay struct {
69
- cfg Config
70
- stack *stack
71
- listener net.Listener
72
- server *http.Server
69
+ cfg Config
70
+ stack *stack
71
+ listener net.Listener
72
+ server *http.Server
73
+ transport *http.Transport
74
+ client *http.Client
75
}
76
77
func NewOverlay(cfg Config, handler http.Handler) (*Overlay, error) {
@@ -98,13 +100,26 @@ func NewOverlay(cfg Config, handler http.Handler) (*Overlay, error) {
100
ReadHeaderTimeout: 10 * time.Second,
101
}
102
103
+ transport := &http.Transport{
104
+ DialContext: stack.DialContext,
105
+ TLSHandshakeTimeout: 10 * time.Second,
106
+ MaxIdleConns: 100,
107
+ IdleConnTimeout: 90 * time.Second,
108
+ ResponseHeaderTimeout: 30 * time.Second,
109
+ ExpectContinueTimeout: 1 * time.Second,
110
+ ForceAttemptHTTP2: false,
111
+ }
112
+ client := &http.Client{Transport: transport}
113
+
114
publicCfg := cfg.Copy()
115
publicCfg.PrivateKey = ""
116
return &Overlay{
104
- cfg: publicCfg,
105
- stack: stack,
106
- listener: listener,
107
- server: server,
117
+ cfg: publicCfg,
118
+ stack: stack,
119
+ listener: listener,
120
+ server: server,
121
+ transport: transport,
122
+ client: client,
123
}, nil
124
}
125
@@ -139,6 +154,9 @@ func (o *Overlay) Shutdown(ctx context.Context) error {
154
shutdownErr = errors.Join(shutdownErr, err)
155
}
156
}
157
+ if o.transport != nil {
158
+ o.transport.CloseIdleConnections()
159
+ }
160
if o.listener != nil {
161
err := o.listener.Close()
162
if err != nil && !errors.Is(err, net.ErrClosed) {
@@ -155,12 +173,7 @@ func (o *Overlay) Client() *http.Client {
173
if o == nil || o.stack == nil {
174
return nil
175
}
158
- return &http.Client{
159
- Transport: &http.Transport{
160
- DialContext: o.stack.DialContext,
161
- ForceAttemptHTTP2: false,
162
- },
163
- }
176
+ return o.client
177
}
178
179
func (o *Overlay) DiscoverRelay(ctx context.Context, relay types.RelayDescriptor) (types.DiscoveryResponse, error) {