func()

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()
			}
		}
	}
}