hub.fastgit.org/hashicorp/consul.git@v1.4.5/agent/consul/flood.go (about) 1 package consul 2 3 import ( 4 "time" 5 6 "github.com/hashicorp/consul/agent/router" 7 "github.com/hashicorp/serf/serf" 8 ) 9 10 // FloodNotify lets all the waiting Flood goroutines know that some change may 11 // have affected them. 12 func (s *Server) FloodNotify() { 13 s.floodLock.RLock() 14 defer s.floodLock.RUnlock() 15 16 for _, ch := range s.floodCh { 17 select { 18 case ch <- struct{}{}: 19 default: 20 } 21 } 22 } 23 24 // Flood is a long-running goroutine that floods servers from the LAN to the 25 // given global Serf instance, such as the WAN. This will exit once either of 26 // the Serf instances are shut down. 27 func (s *Server) Flood(addrFn router.FloodAddrFn, portFn router.FloodPortFn, global *serf.Serf) { 28 s.floodLock.Lock() 29 floodCh := make(chan struct{}) 30 s.floodCh = append(s.floodCh, floodCh) 31 s.floodLock.Unlock() 32 33 ticker := time.NewTicker(s.config.SerfFloodInterval) 34 defer ticker.Stop() 35 defer func() { 36 s.floodLock.Lock() 37 defer s.floodLock.Unlock() 38 39 for i, ch := range s.floodCh { 40 if ch == floodCh { 41 s.floodCh = append(s.floodCh[:i], s.floodCh[i+1:]...) 42 return 43 } 44 } 45 panic("flood channels out of sync") 46 }() 47 48 for { 49 select { 50 case <-s.serfLAN.ShutdownCh(): 51 return 52 53 case <-global.ShutdownCh(): 54 return 55 56 case <-ticker.C: 57 goto FLOOD 58 59 case <-floodCh: 60 goto FLOOD 61 } 62 63 FLOOD: 64 router.FloodJoins(s.logger, addrFn, portFn, s.config.Datacenter, s.serfLAN, global) 65 } 66 }