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  }