2
0
mirror of synced 2025-02-24 06:38:14 +00:00

Use timers for duplicate requests

Nothing was triggering request updates when timeouts expired. This is the simplest fix, no performance considered.
This commit is contained in:
Matt Joiner 2018-06-30 00:10:31 +10:00
parent 716fd43d44
commit b2117bc571
2 changed files with 24 additions and 11 deletions

View File

@ -512,7 +512,17 @@ func (cn *connection) request(r request, mw messageWriter) bool {
}
cn.validReceiveChunks[r] = struct{}{}
cn.t.pendingRequests[r]++
cn.t.lastRequested[r] = time.Now()
cn.t.lastRequested[r] = time.AfterFunc(cn.t.duplicateRequestTimeout, func() {
torrent.Add("duplicate request timeouts", 1)
cn.mu().Lock()
defer cn.mu().Unlock()
delete(cn.t.lastRequested, r)
for cn := range cn.t.conns {
if cn.PeerHasPiece(pieceIndex(r.Index)) {
cn.updateRequests()
}
}
})
cn.updateExpectingChunks()
return mw(pp.Message{
Type: pp.Request,
@ -761,13 +771,10 @@ func (cn *connection) iterPendingRequests(piece int, f func(request) bool) bool
return iterUndirtiedChunks(piece, cn.t, func(cs chunkSpec) bool {
r := request{pp.Integer(piece), cs}
if cn.t.requestStrategy == 3 {
lr := cn.t.lastRequested[r]
if !lr.IsZero() {
if time.Since(lr) < cn.t.duplicateRequestTimeout {
if _, ok := cn.t.lastRequested[r]; ok {
// This piece has been requested on another connection, and
// the duplicate request timer is still running.
return true
} else {
torrent.Add("requests duplicated due to timeout", 1)
}
}
}
return f(r)
@ -1470,7 +1477,10 @@ func (c *connection) deleteRequest(r request) bool {
}
delete(c.requests, r)
c.updateExpectingChunks()
if t, ok := c.t.lastRequested[r]; ok {
t.Stop()
delete(c.t.lastRequested, r)
}
pr := c.t.pendingRequests
pr[r]--
n := pr[r]

View File

@ -147,7 +147,7 @@ type Torrent struct {
pendingRequests map[request]int
// The last time we requested a chunk. Deleting the request from any
// connection will clear this value.
lastRequested map[request]time.Time
lastRequested map[request]*time.Timer
}
func (t *Torrent) tickleReaders() {
@ -407,7 +407,7 @@ func (t *Torrent) onSetInfo() {
t.gotMetainfo.Set()
t.updateWantPeersEvent()
t.pendingRequests = make(map[request]int)
t.lastRequested = make(map[request]time.Time)
t.lastRequested = make(map[request]*time.Timer)
}
// Called when metadata for a torrent becomes available.
@ -1240,6 +1240,9 @@ func (t *Torrent) assertNoPendingRequests() {
if len(t.pendingRequests) != 0 {
panic(t.pendingRequests)
}
if len(t.lastRequested) != 0 {
panic(t.lastRequested)
}
}
func (t *Torrent) dropConnection(c *connection) {