"expvar"
"fmt"
"io"
+ "math"
"net"
"net/http"
"sort"
defer t.dropConnection(c)
c.startWriter()
cl.sendInitialMessages(c, t)
+ c.updateRequestsTimer = time.AfterFunc(math.MaxInt64, func() {
+ if c.needRequestUpdate != "" {
+ return
+ }
+ if c.actualRequestState.Requests.IsEmpty() {
+ panic("updateRequestsTimer should have been stopped")
+ }
+ c.updateRequests("updateRequestsTimer")
+ })
+ c.updateRequestsTimer.Stop()
err := c.mainReadLoop()
if err != nil {
return fmt.Errorf("main read loop: %w", err)
// Stuff controlled by the local peer.
needRequestUpdate string
actualRequestState requestState
+ updateRequestsTimer *time.Timer
cancelledRequests roaring.Bitmap
lastBecameInterested time.Time
priorInterest time.Duration
if cn.pex.IsEnabled() {
cn.pex.Close()
}
+ if cn.updateRequestsTimer != nil {
+ cn.updateRequestsTimer.Stop()
+ }
cn.tickleWriter()
if cn.conn != nil {
cn.conn.Close()
}
func (p *Peer) applyRequestState(next requestState) bool {
- current := p.actualRequestState
+ current := &p.actualRequestState
if !p.setInterested(next.Interested) {
return false
}
}
next.Requests.Iterate(func(req uint32) bool {
if p.cancelledRequests.Contains(req) {
- log.Printf("waiting for cancelled request %v", req)
- return false
+ // Waiting for a reject or piece message, which will suitably trigger us to update our
+ // requests, so we can skip this one with no additional consideration.
+ return true
}
if maxRequests(current.Requests.GetCardinality()) >= p.nominalMaxRequests() {
log.Printf("not assigning all requests [desired=%v, cancelled=%v, max=%v]",
})
if more {
p.needRequestUpdate = ""
+ if current.Requests.IsEmpty() {
+ p.updateRequestsTimer.Stop()
+ } else {
+ p.updateRequestsTimer.Reset(time.Second)
+ }
}
return more
}