mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2026-05-06 14:03:40 +08:00
fix: resolve concurrent map iteration and map write crash in sitecheck (#1661)
Fixed fatal error 'concurrent map iteration and map write' that caused nginx-ui nodes to crash and become unresponsive. The issue occurred when the sitecheck CollectSites() method iterated over site.IndexedSites while the cache scanner's scanForSite() was concurrently modifying the same map. This race condition caused sporadic crashes. Solution: - Added GetAllIndexedSites() function in internal/site/index.go that safely returns a snapshot copy of the IndexedSites map while holding the read lock - Modified CollectSites() in internal/sitecheck/checker.go to use this thread-safe function instead of directly accessing the global map Fixes #1673 Co-authored-by: Cursor Agent <cursoragent@cursor.com>
This commit is contained in:
@@ -37,6 +37,19 @@ func GetIndexedSite(path string) *Index {
|
||||
return &Index{}
|
||||
}
|
||||
|
||||
// GetAllIndexedSites returns a snapshot copy of all indexed sites.
|
||||
// This is safe for concurrent access as it holds the read lock while copying.
|
||||
func GetAllIndexedSites() map[string]*Index {
|
||||
siteIndexMutex.RLock()
|
||||
defer siteIndexMutex.RUnlock()
|
||||
|
||||
result := make(map[string]*Index, len(IndexedSites))
|
||||
for k, v := range IndexedSites {
|
||||
result[k] = v
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func init() {
|
||||
cache.RegisterCallback("site.scanForSite", scanForSite)
|
||||
}
|
||||
|
||||
@@ -82,11 +82,14 @@ func (sc *SiteChecker) CollectSites() {
|
||||
// Clear existing sites
|
||||
sc.sites = make(map[string]*SiteInfo)
|
||||
|
||||
// Get a thread-safe snapshot of indexed sites to avoid concurrent map access
|
||||
indexedSites := site.GetAllIndexedSites()
|
||||
|
||||
// Debug: log indexed sites count
|
||||
logger.Debugf("Found %d indexed sites", len(site.IndexedSites))
|
||||
logger.Debugf("Found %d indexed sites", len(indexedSites))
|
||||
|
||||
// Collect URLs from indexed sites, but only from enabled sites
|
||||
for siteName, indexedSite := range site.IndexedSites {
|
||||
for siteName, indexedSite := range indexedSites {
|
||||
// Check site status - only collect from enabled sites
|
||||
siteStatus := site.GetSiteStatus(siteName)
|
||||
if siteStatus != site.StatusEnabled {
|
||||
|
||||
Reference in New Issue
Block a user