7 "github.com/anacrolix/missinggo/v2/bitmap"
9 "github.com/anacrolix/chansync"
10 request_strategy "github.com/anacrolix/torrent/request-strategy"
11 "github.com/anacrolix/torrent/types"
14 func (cl *Client) requester() {
16 update := func() chansync.Signaled {
20 return cl.updateRequests.Signaled()
23 case <-cl.closed.Done():
25 case <-time.After(100 * time.Millisecond):
28 case <-cl.closed.Done():
31 case <-time.After(time.Second):
36 func (cl *Client) tickleRequester() {
37 cl.updateRequests.Broadcast()
40 func (cl *Client) doRequests() {
41 ts := make([]request_strategy.Torrent, 0, len(cl.torrents))
42 for _, t := range cl.torrents {
43 rst := request_strategy.Torrent{
44 StableId: uintptr(unsafe.Pointer(t)),
47 rst.Capacity = t.storage.Capacity
49 rst.Pieces = make([]request_strategy.Piece, 0, len(t.pieces))
50 for i := range t.pieces {
52 rst.Pieces = append(rst.Pieces, request_strategy.Piece{
53 Request: !t.ignorePieceForRequests(i),
54 Priority: p.purePriority(),
55 Partial: t.piecePartiallyDownloaded(i),
56 Availability: p.availability,
57 Length: int64(p.length()),
58 NumPendingChunks: int(t.pieceNumPendingChunks(i)),
59 IterPendingChunks: func(f func(types.ChunkSpec)) {
60 p.iterUndirtiedChunks(func(cs ChunkSpec) bool {
67 t.iterPeers(func(p *Peer) {
71 if p.piecesReceivedSinceLastRequestUpdate > p.maxPiecesReceivedBetweenRequestUpdates {
72 p.maxPiecesReceivedBetweenRequestUpdates = p.piecesReceivedSinceLastRequestUpdate
74 p.piecesReceivedSinceLastRequestUpdate = 0
75 rst.Peers = append(rst.Peers, request_strategy.Peer{
76 HasPiece: p.peerHasPiece,
77 MaxRequests: p.nominalMaxRequests(),
78 HasExistingRequest: func(r request_strategy.Request) bool {
79 _, ok := p.actualRequestState.Requests[r]
82 Choking: p.peerChoking,
83 PieceAllowedFast: func(i pieceIndex) bool {
84 return p.peerAllowedFast.Contains(bitmap.BitIndex(i))
86 DownloadRate: p.downloadRate(),
87 Age: time.Since(p.completedHandshake),
90 ptr: uintptr(unsafe.Pointer(p)),
96 nextPeerStates := request_strategy.Run(request_strategy.Input{
98 MaxUnverifiedBytes: cl.config.MaxUnverifiedBytes,
100 for p, state := range nextPeerStates {
101 setPeerNextRequestState(p, state)
110 func (p peerId) Uintptr() uintptr {
114 func setPeerNextRequestState(_p request_strategy.PeerId, rp request_strategy.PeerNextRequestState) {
115 p := _p.(peerId).Peer
116 p.nextRequestState = rp
117 p.onNextRequestStateChanged()
120 func (p *Peer) applyNextRequestState() bool {
121 next := p.nextRequestState
122 current := p.actualRequestState
123 if !p.setInterested(next.Interested) {
126 for req := range current.Requests {
127 if _, ok := next.Requests[req]; !ok {
133 for req := range next.Requests {
134 more, err := p.request(req)