From 4471fb5dff0a100aef3681cb45e02ec7c06f5fed Mon Sep 17 00:00:00 2001 From: Xiage Date: Mon, 30 Mar 2026 11:07:05 +0800 Subject: [PATCH] fix: release mu before calling Instance.Close() in sweeper Collect expired entries under lock, then release lock and close instances outside the critical section to avoid blocking all map operations if Close() is slow. --- xray/xray.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/xray/xray.go b/xray/xray.go index ae4c558..166cce5 100644 --- a/xray/xray.go +++ b/xray/xray.go @@ -86,15 +86,32 @@ func init() { func sweeper() { for { time.Sleep(sweepInterval) + + // Collect expired URLs under lock, then release lock before closing + // to avoid blocking all map operations while Instance.Close() runs. + var expired []struct { + url string + srv *Server + } mu.Lock() now := time.Now() for url, srv := range servers { if !srv.DrainedAt.IsZero() && now.Sub(srv.DrainedAt) > drainTimeout { - srv.Instance.Close() //nolint: errcheck - delete(servers, url) + expired = append(expired, struct { + url string + srv *Server + }{url, srv}) } } mu.Unlock() + + // Close instances outside the critical section. + for _, e := range expired { + e.srv.Instance.Close() //nolint: errcheck + mu.Lock() + delete(servers, e.url) + mu.Unlock() + } } }