package consul import ( "time" "github.com/hashicorp/consul/agent/router" "github.com/hashicorp/serf/serf" ) // FloodNotify lets all the waiting Flood goroutines know that some change may // have affected them. func (s *Server) FloodNotify() { s.floodLock.RLock() defer s.floodLock.RUnlock() for _, ch := range s.floodCh { select { case ch <- struct{}{}: default: } } } // Flood is a long-running goroutine that floods servers from the LAN to the // given global Serf instance, such as the WAN. This will exit once either of // the Serf instances are shut down. func (s *Server) Flood(addrFn router.FloodAddrFn, dstSerf *serf.Serf) { s.floodLock.Lock() floodCh := make(chan struct{}) s.floodCh = append(s.floodCh, floodCh) s.floodLock.Unlock() ticker := time.NewTicker(s.config.SerfFloodInterval) defer ticker.Stop() defer func() { s.floodLock.Lock() defer s.floodLock.Unlock() for i, ch := range s.floodCh { if ch == floodCh { s.floodCh = append(s.floodCh[:i], s.floodCh[i+1:]...) return } } panic("flood channels out of sync") }() for { select { case <-s.serfLAN.ShutdownCh(): return case <-dstSerf.ShutdownCh(): return case <-ticker.C: router.FloodJoins(s.logger, addrFn, s.config.Datacenter, s.serfLAN, dstSerf) case <-floodCh: router.FloodJoins(s.logger, addrFn, s.config.Datacenter, s.serfLAN, dstSerf) } } }