in lib/torrent/scheduler/events.go [393:438]
func (e preemptionTickEvent) apply(s *state) {
for _, c := range s.conns.ActiveConns() {
ctrl, ok := s.torrentControls[c.InfoHash()]
if !ok {
s.log("conn", c).Error(
"Invariant violation: active conn not assigned to dispatcher")
c.Close()
continue
}
lastProgress := timeutil.MostRecent(
c.CreatedAt(),
ctrl.dispatcher.LastGoodPieceReceived(c.PeerID()),
ctrl.dispatcher.LastPieceSent(c.PeerID()))
if s.sched.clock.Now().Sub(lastProgress) > s.sched.config.ConnTTI {
s.log("conn", c).Info("Closing idle conn")
c.Close()
continue
}
if s.sched.clock.Now().Sub(c.CreatedAt()) > s.sched.config.ConnTTL {
s.log("conn", c).Info("Closing expired conn")
c.Close()
continue
}
}
for h, ctrl := range s.torrentControls {
idleSeeder :=
ctrl.dispatcher.Complete() &&
s.sched.clock.Now().Sub(ctrl.dispatcher.LastReadTime()) >= s.sched.config.SeederTTI
if idleSeeder {
s.sched.torrentlog.SeedTimeout(ctrl.dispatcher.Digest(), h)
}
idleLeecher :=
!ctrl.dispatcher.Complete() &&
s.sched.clock.Now().Sub(ctrl.dispatcher.LastWriteTime()) >= s.sched.config.LeecherTTI
if idleLeecher {
s.sched.torrentlog.LeechTimeout(ctrl.dispatcher.Digest(), h)
}
if idleSeeder || idleLeecher {
s.log("hash", h, "inprogress", !ctrl.dispatcher.Complete()).Info("Removing idle torrent")
s.removeTorrent(h, ErrTorrentTimeout)
}
}
}