in ntp/responder/server/server.go [59:126]
func (s *Server) Start(ctx context.Context, cancelFunc context.CancelFunc) {
log.Infof("Creating %d goroutine workers", s.Workers)
s.tasks = make(chan task, s.Workers)
// Pre-create workers
for i := 0; i < s.Workers; i++ {
go s.startWorker()
}
log.Infof("Starting %d listener(s)", len(s.ListenConfig.IPs))
for _, ip := range s.ListenConfig.IPs {
log.Infof("Starting listener on %s:%d", ip.String(), s.ListenConfig.Port)
go func(ip net.IP) {
s.Stats.IncListeners()
// Need to be sure IP is on interface:
if err := s.addIPToInterface(ip); err != nil {
log.Errorf("[server]: %v", err)
}
conn, err := net.ListenUDP("udp", &net.UDPAddr{IP: ip, Port: s.ListenConfig.Port})
if err != nil {
log.Fatalf("listening error: %v", err)
}
defer conn.Close()
if err != nil {
log.Fatalf("failed to start listener: %v", err)
}
s.startListener(conn)
s.Stats.DecListeners()
}(ip)
}
// Run checker periodically
go func() {
for {
time.Sleep(time.Minute)
log.Debug("[Checker] running internal health checks")
err := s.Checker.Check()
if err != nil {
log.Errorf("[Checker] internal error: %v", err)
cancelFunc()
return
}
}
}()
for {
select {
case <-ctx.Done():
break
case <-time.After(30 * time.Second):
if s.ListenConfig.ShouldAnnounce {
// First run will be 30 seconds delayed
log.Debug("Requesting VIPs announce")
err := s.Announce.Advertise(s.ListenConfig.IPs)
if err != nil {
log.Errorf("Error during announcement: %v", err)
s.Stats.ResetAnnounce()
} else {
s.Stats.SetAnnounce()
}
} else {
s.Stats.ResetAnnounce()
}
}
}
}