88 "time"
99
1010 "github.com/0xJacky/Nginx-UI/internal/cache"
11+ "github.com/0xJacky/Nginx-UI/model"
1112 "github.com/uozi-tech/cosy/logger"
1213)
1314
@@ -32,13 +33,16 @@ type Service struct {
3233 availabilityMap map [string ]* Status // key: host:port
3334 configTargets map [string ][]string // configPath -> []targetKeys
3435 // Public upstream definitions storage
35- Upstreams map [string ]* Definition // key: upstream name
36- upstreamsMutex sync.RWMutex
37- targetsMutex sync.RWMutex
38- lastUpdateTime time.Time
39- testInProgress bool
40- testMutex sync.Mutex
41- disabledSocketsChecker func () map [string ]bool
36+ Upstreams map [string ]* Definition // key: upstream name
37+ upstreamsMutex sync.RWMutex
38+ targetsMutex sync.RWMutex
39+ lastUpdateTime time.Time
40+ testInProgress bool
41+ testMutex sync.Mutex
42+ cachedDisabledSockets map [string ]bool
43+ disabledSocketsCacheMutex sync.RWMutex
44+ disabledSocketsCacheExpiry time.Time
45+ disabledSocketsCacheDuration time.Duration
4246}
4347
4448var (
@@ -66,11 +70,12 @@ func formatSocketAddress(host, port string) string {
6670func GetUpstreamService () * Service {
6771 serviceOnce .Do (func () {
6872 upstreamService = & Service {
69- targets : make (map [string ]* TargetInfo ),
70- availabilityMap : make (map [string ]* Status ),
71- configTargets : make (map [string ][]string ),
72- Upstreams : make (map [string ]* Definition ),
73- lastUpdateTime : time .Now (),
73+ targets : make (map [string ]* TargetInfo ),
74+ availabilityMap : make (map [string ]* Status ),
75+ configTargets : make (map [string ][]string ),
76+ Upstreams : make (map [string ]* Definition ),
77+ lastUpdateTime : time .Now (),
78+ disabledSocketsCacheDuration : 30 * time .Second ,
7479 }
7580 })
7681 return upstreamService
@@ -237,11 +242,8 @@ func (s *Service) PerformAvailabilityTest() {
237242
238243 // logger.Debug("Performing availability test for", targetCount, "unique targets")
239244
240- // Get disabled sockets from database
241- disabledSockets := make (map [string ]bool )
242- if s .disabledSocketsChecker != nil {
243- disabledSockets = s .disabledSocketsChecker ()
244- }
245+ // Get disabled sockets from cache or database
246+ disabledSockets := s .getDisabledSockets ()
245247
246248 // Separate targets into traditional and consul groups from the start
247249 s .targetsMutex .RLock ()
@@ -307,9 +309,59 @@ func (s *Service) findUpstreamNameForTarget(target ProxyTarget) string {
307309 return ""
308310}
309311
310- // SetDisabledSocketsChecker sets a callback function to check disabled sockets
311- func (s * Service ) SetDisabledSocketsChecker (checker func () map [string ]bool ) {
312- s .disabledSocketsChecker = checker
312+ // getDisabledSockets queries the database for disabled sockets with caching
313+ func (s * Service ) getDisabledSockets () map [string ]bool {
314+ // Check if cache is still valid
315+ s .disabledSocketsCacheMutex .RLock ()
316+ if time .Now ().Before (s .disabledSocketsCacheExpiry ) && s .cachedDisabledSockets != nil {
317+ // Return a copy of the cached data
318+ result := make (map [string ]bool , len (s .cachedDisabledSockets ))
319+ for k , v := range s .cachedDisabledSockets {
320+ result [k ] = v
321+ }
322+ s .disabledSocketsCacheMutex .RUnlock ()
323+ return result
324+ }
325+ s .disabledSocketsCacheMutex .RUnlock ()
326+
327+ // Cache expired or not initialized, refresh from database
328+ disabled := make (map [string ]bool )
329+
330+ db := model .UseDB ()
331+ if db == nil {
332+ return disabled
333+ }
334+
335+ var configs []model.UpstreamConfig
336+ if err := db .Where ("enabled = ?" , false ).Find (& configs ).Error ; err != nil {
337+ logger .Error ("Failed to query disabled sockets:" , err )
338+ return disabled
339+ }
340+
341+ for _ , config := range configs {
342+ disabled [config .Socket ] = true
343+ }
344+
345+ // Update cache
346+ s .disabledSocketsCacheMutex .Lock ()
347+ s .cachedDisabledSockets = disabled
348+ s .disabledSocketsCacheExpiry = time .Now ().Add (s .disabledSocketsCacheDuration )
349+ s .disabledSocketsCacheMutex .Unlock ()
350+
351+ // Return a copy to prevent external modification
352+ result := make (map [string ]bool , len (disabled ))
353+ for k , v := range disabled {
354+ result [k ] = v
355+ }
356+ return result
357+ }
358+
359+ // InvalidateDisabledSocketsCache invalidates the cache, forcing next read to refresh from database
360+ func (s * Service ) InvalidateDisabledSocketsCache () {
361+ s .disabledSocketsCacheMutex .Lock ()
362+ defer s .disabledSocketsCacheMutex .Unlock ()
363+ s .disabledSocketsCacheExpiry = time.Time {} // Set to zero time to force refresh
364+ logger .Debug ("Disabled sockets cache invalidated" )
313365}
314366
315367// ClearTargets clears all targets (useful for testing or reloading)
0 commit comments