peerconn.go | 12 +++++++++--- webseed-peer.go | 21 +++++++++++++++------ diff --git a/peerconn.go b/peerconn.go index cf9ace9ddd31c72dda109d60a9f1248c1eb89dd2..de82cf3b2a44e3fb18940ea6e6ad87d0085ea073 100644 --- a/peerconn.go +++ b/peerconn.go @@ -312,6 +312,9 @@ } func (cn *Peer) writeStatus(w io.Writer, t *Torrent) { // \t isn't preserved in
blocks?
+ if cn.closed.IsSet() {
+ fmt.Fprint(w, "CLOSED: ")
+ }
fmt.Fprintln(w, cn.connStatusString())
fmt.Fprintf(w, " last msg: %s, connected: %s, last helpful: %s, itime: %s, etime: %s\n",
eventAgeString(cn.lastMessageReceived),
@@ -787,11 +790,14 @@ func (cn *Peer) shouldRequestWithoutBias() bool {
return cn.t.requestStrategy.shouldRequestWithoutBias(cn.requestStrategyConnection())
}
-func (cn *Peer) iterPendingPieces(f func(pieceIndex) bool) bool {
+func (cn *Peer) iterPendingPieces(f func(pieceIndex) bool) {
if !cn.t.haveInfo() {
- return false
+ return
+ }
+ if cn.closed.IsSet() {
+ return
}
- return cn.t.requestStrategy.iterPendingPieces(cn, f)
+ cn.t.requestStrategy.iterPendingPieces(cn, f)
}
func (cn *Peer) iterPendingPiecesUntyped(f iter.Callback) {
cn.iterPendingPieces(func(i pieceIndex) bool { return f(i) })
diff --git a/webseed-peer.go b/webseed-peer.go
index 72c9173d44f7448a56303500cfc4950270e6b655..e436f8aab0fd54bbf9c0ee3c1ceeaa6c60a24932 100644
--- a/webseed-peer.go
+++ b/webseed-peer.go
@@ -1,6 +1,8 @@
package torrent
import (
+ "context"
+ "errors"
"fmt"
"strings"
"sync"
@@ -10,7 +12,6 @@ "github.com/anacrolix/torrent/metainfo"
pp "github.com/anacrolix/torrent/peer_protocol"
"github.com/anacrolix/torrent/segments"
"github.com/anacrolix/torrent/webseed"
- "github.com/pkg/errors"
)
type webseedPeer struct {
@@ -64,9 +65,11 @@
func (ws *webseedPeer) doRequest(r Request) {
webseedRequest := ws.client.NewRequest(ws.intoSpec(r))
ws.activeRequests[r] = webseedRequest
- ws.requesterCond.L.Unlock()
- ws.requestResultHandler(r, webseedRequest)
- ws.requesterCond.L.Lock()
+ func() {
+ ws.requesterCond.L.Unlock()
+ defer ws.requesterCond.L.Lock()
+ ws.requestResultHandler(r, webseedRequest)
+ }()
delete(ws.activeRequests, r)
}
@@ -99,6 +102,10 @@ ws.peer.doRequestState()
}
func (ws *webseedPeer) onClose() {
+ ws.peer.logger.Print("closing")
+ for _, r := range ws.activeRequests {
+ r.Cancel()
+ }
ws.requesterCond.Broadcast()
}
@@ -107,12 +114,14 @@ result := <-webseedRequest.Result
ws.peer.t.cl.lock()
defer ws.peer.t.cl.unlock()
if result.Err != nil {
- ws.peer.logger.Printf("Request %v rejected: %v", r, result.Err)
+ if !errors.Is(result.Err, context.Canceled) {
+ ws.peer.logger.Printf("Request %v rejected: %v", r, result.Err)
+ }
// Always close for now. We need to filter out temporary errors, but this is a nightmare in
// Go. Currently a bad webseed URL can starve out the good ones due to the chunk selection
// algorithm.
const closeOnAllErrors = false
- if closeOnAllErrors || strings.Contains(errors.Cause(result.Err).Error(), "unsupported protocol scheme") {
+ if closeOnAllErrors || strings.Contains(result.Err.Error(), "unsupported protocol scheme") {
ws.peer.close()
} else {
ws.peer.remoteRejectedRequest(r)