2
0
mirror of synced 2025-02-24 14:48:27 +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.validReceiveChunks[r] = struct{}{}
cn.t.pendingRequests[r]++ 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() cn.updateExpectingChunks()
return mw(pp.Message{ return mw(pp.Message{
Type: pp.Request, 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 { return iterUndirtiedChunks(piece, cn.t, func(cs chunkSpec) bool {
r := request{pp.Integer(piece), cs} r := request{pp.Integer(piece), cs}
if cn.t.requestStrategy == 3 { if cn.t.requestStrategy == 3 {
lr := cn.t.lastRequested[r] if _, ok := cn.t.lastRequested[r]; ok {
if !lr.IsZero() { // This piece has been requested on another connection, and
if time.Since(lr) < cn.t.duplicateRequestTimeout { // the duplicate request timer is still running.
return true return true
} else {
torrent.Add("requests duplicated due to timeout", 1)
}
} }
} }
return f(r) return f(r)
@ -1470,7 +1477,10 @@ func (c *connection) deleteRequest(r request) bool {
} }
delete(c.requests, r) delete(c.requests, r)
c.updateExpectingChunks() c.updateExpectingChunks()
delete(c.t.lastRequested, r) if t, ok := c.t.lastRequested[r]; ok {
t.Stop()
delete(c.t.lastRequested, r)
}
pr := c.t.pendingRequests pr := c.t.pendingRequests
pr[r]-- pr[r]--
n := pr[r] n := pr[r]

View File

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