github.com/anacrolix/torrent@v1.61.0/client-unlock-handlers.go (about)

     1  package torrent
     2  
     3  import (
     4  	"log/slog"
     5  	"time"
     6  
     7  	g "github.com/anacrolix/generics"
     8  	"github.com/anacrolix/missinggo/v2/panicif"
     9  )
    10  
    11  type torrentUnlockActions struct {
    12  	updateRegularTrackerAnnouncing bool
    13  	updateComplete                 bool
    14  }
    15  
    16  // A non-dynamic way to register handlers to run just once when the client is unlocked.
    17  type clientUnlockHandlers struct {
    18  	torrentActions     map[*Torrent]torrentUnlockActions
    19  	changedPieceStates map[*Piece]struct{}
    20  }
    21  
    22  func (me *clientUnlockHandlers) init() {
    23  	g.MakeMap(&me.torrentActions)
    24  	g.MakeMap(&me.changedPieceStates)
    25  }
    26  
    27  func (me *clientUnlockHandlers) deferUpdateTorrentRegularTrackerAnnouncing(t *Torrent) {
    28  	g.MakeMapIfNil(&me.torrentActions)
    29  	value := me.torrentActions[t]
    30  	value.updateRegularTrackerAnnouncing = true
    31  	me.torrentActions[t] = value
    32  }
    33  
    34  func (me *clientUnlockHandlers) addUpdateComplete(t *Torrent) {
    35  	v := me.torrentActions[t]
    36  	v.updateComplete = true
    37  	me.torrentActions[t] = v
    38  }
    39  
    40  func (me *clientUnlockHandlers) run(logger *slog.Logger) {
    41  	trackers := 0
    42  	started := time.Now()
    43  	for t, v := range me.torrentActions {
    44  		if v.updateRegularTrackerAnnouncing {
    45  			trackers++
    46  			t.updateRegularTrackerAnnouncing()
    47  		}
    48  		if v.updateComplete {
    49  			t.updateComplete()
    50  		}
    51  		delete(me.torrentActions, t)
    52  	}
    53  	since := time.Since(started)
    54  	// Around here the Go scheduler starts to do crazy stuff.
    55  	if since > 20*time.Millisecond {
    56  		logger.Warn("client unlock handlers took a long time", "duration", since, "trackers", trackers)
    57  	}
    58  	for p := range me.changedPieceStates {
    59  		p.publishStateChange()
    60  		delete(me.changedPieceStates, p)
    61  	}
    62  	panicif.NotEq(len(me.torrentActions), 0)
    63  }