in ptp/ptp4u/server/server.go [56:157]
func (s *Server) Start() error {
// Set clock identity
iface, err := net.InterfaceByName(s.Config.Interface)
if err != nil {
return fmt.Errorf("unable to get mac address of the interface: %v", err)
}
s.Config.clockIdentity, err = ptp.NewClockIdentity(iface.HardwareAddr)
if err != nil {
return fmt.Errorf("unable to get the Clock Identity (EUI-64 address) of the interface: %v", err)
}
// initialize the context for the subscriptions
s.ctx, s.cancel = context.WithCancel(context.Background())
// Call wg.Add(1) ONLY once
// If ANY goroutine finishes no matter how many of them we run
// wg.Done will unblock
var wg sync.WaitGroup
wg.Add(1)
// start X workers
s.sw = make([]*sendWorker, s.Config.SendWorkers)
for i := 0; i < s.Config.SendWorkers; i++ {
// Each worker to monitor own queue
s.sw[i] = newSendWorker(i, s.Config, s.Stats)
go func(i int) {
defer wg.Done()
s.sw[i].Start()
}(i)
}
go func() {
defer wg.Done()
s.startGeneralListener()
}()
go func() {
defer wg.Done()
s.startEventListener()
}()
// Run active metric reporting
go func() {
defer wg.Done()
for {
<-time.After(s.Config.MetricInterval)
for _, w := range s.sw {
w.inventoryClients()
}
s.Stats.SetUTCOffset(int64(s.Config.UTCOffset.Seconds()))
s.Stats.Snapshot()
s.Stats.Reset()
}
}()
// Drain check
go func() {
defer wg.Done()
ticker := time.NewTicker(s.Config.DrainInterval)
defer ticker.Stop()
for ; true; <-ticker.C {
var drain bool
for _, check := range s.Checks {
if check.Check() {
drain = true
log.Warningf("%T engaged shifting traffic", check)
break
}
}
if drain {
s.Drain()
s.Stats.SetDrain(1)
} else {
s.Undrain()
s.Stats.SetDrain(0)
}
}
}()
// Update UTC offset periodically
go func() {
defer wg.Done()
for {
<-time.After(1 * time.Minute)
if s.Config.Leapsectz {
if err := s.Config.SetUTCOffsetFromLeapsectz(); err != nil {
log.Errorf("Failed to update UTC offset: %v. Keeping the last known: %s", err, s.Config.UTCOffset)
}
} else if s.Config.SHM {
if err := s.Config.SetUTCOffsetFromSHM(); err != nil {
log.Errorf("Failed to update UTC offset: %v. Keeping the last known: %s", err, s.Config.UTCOffset)
}
}
log.Debugf("UTC offset is: %v", s.Config.UTCOffset.Seconds())
}
}()
// Wait for ANY gorouine to finish
wg.Wait()
return fmt.Errorf("one of server routines finished")
}