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:
parent
716fd43d44
commit
b2117bc571
@ -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]
|
||||||
|
@ -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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user