Skip to content

Commit 2c580ed

Browse files
author
dovtang
committed
fix: prevent service degradation on config reload failure
When applyConfig() fails during hot reload, the old proxy was being destroyed before the new proxy was successfully initialized, causing partial service outage. Changes: - main.go: Use temporary variable to create and validate new proxy before replacing the global instance. On failure, cleanup new proxy and keep old proxy running. - proxy.go: Fix bug where maxIdleConns was incorrectly assigned MaxIdleConnsPerHost
1 parent 3aea406 commit 2c580ed

2 files changed

Lines changed: 20 additions & 6 deletions

File tree

main.go

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -299,12 +299,26 @@ func proxyConfigChanged(cfgCp *config.ConnectionPool, rp *reverseProxy) bool {
299299
}
300300

301301
func applyConfig(cfg *config.Config) error {
302-
if proxy == nil || proxyConfigChanged(&cfg.ConnectionPool, proxy) {
303-
proxy = newReverseProxy(&cfg.ConnectionPool)
304-
}
305-
if err := proxy.applyConfig(cfg); err != nil {
306-
return err
302+
needNewProxy := proxy == nil || proxyConfigChanged(&cfg.ConnectionPool, proxy)
303+
304+
if needNewProxy {
305+
newProxy := newReverseProxy(&cfg.ConnectionPool)
306+
if err := newProxy.applyConfig(cfg); err != nil {
307+
close(newProxy.reloadSignal)
308+
newProxy.reloadWG.Wait()
309+
return err
310+
}
311+
if proxy != nil {
312+
close(proxy.reloadSignal)
313+
proxy.reloadWG.Wait()
314+
}
315+
proxy = newProxy
316+
} else {
317+
if err := proxy.applyConfig(cfg); err != nil {
318+
return err
319+
}
307320
}
321+
308322
allowedNetworksHTTP.Store(&cfg.Server.HTTP.AllowedNetworks)
309323
allowedNetworksHTTPS.Store(&cfg.Server.HTTPS.AllowedNetworks)
310324
allowedNetworksMetrics.Store(&cfg.Server.Metrics.AllowedNetworks)

proxy.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ func newReverseProxy(cfgCp *config.ConnectionPool) *reverseProxy {
7878
},
7979
reloadSignal: make(chan struct{}),
8080
reloadWG: sync.WaitGroup{},
81-
maxIdleConns: cfgCp.MaxIdleConnsPerHost,
81+
maxIdleConns: cfgCp.MaxIdleConns,
8282
maxIdleConnsPerHost: cfgCp.MaxIdleConnsPerHost,
8383
}
8484
}

0 commit comments

Comments
 (0)