+ // Periodic jobs
+ state.wg.Add(1)
+ go func() {
+ deadlineTicker := time.NewTicker(time.Second)
+ pingTicker := time.NewTicker(PingTimeout)
+ for {
+ select {
+ case <-state.isDead:
+ state.wg.Done()
+ deadlineTicker.Stop()
+ pingTicker.Stop()
+ return
+ case now := <-deadlineTicker.C:
+ if (now.Sub(state.RxLastNonPing) >= state.onlineDeadline &&
+ now.Sub(state.TxLastNonPing) >= state.onlineDeadline) ||
+ (state.maxOnlineTime > 0 && state.mustFinishAt.Before(now)) ||
+ (now.Sub(state.RxLastSeen) >= 2*PingTimeout) {
+ state.SetDead()
+ conn.Close() // #nosec G104
+ }
+ case now := <-pingTicker.C:
+ if now.After(state.TxLastSeen.Add(PingTimeout)) {
+ state.wg.Add(1)
+ go func() {
+ state.pings <- struct{}{}
+ state.wg.Done()
+ }()
+ }
+ }
+ }
+ }()
+
+ // Spool checker and INFOs sender of appearing files