]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Fix closing of webseed peers
authorMatt Joiner <anacrolix@gmail.com>
Tue, 9 Feb 2021 08:21:54 +0000 (19:21 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 9 Feb 2021 08:21:54 +0000 (19:21 +1100)
peerconn.go
webseed-peer.go

index cf9ace9ddd31c72dda109d60a9f1248c1eb89dd2..de82cf3b2a44e3fb18940ea6e6ad87d0085ea073 100644 (file)
@@ -312,6 +312,9 @@ func (cn *Peer) downloadRate() float64 {
 
 func (cn *Peer) writeStatus(w io.Writer, t *Torrent) {
        // \t isn't preserved in <pre> 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) })
index 72c9173d44f7448a56303500cfc4950270e6b655..e436f8aab0fd54bbf9c0ee3c1ceeaa6c60a24932 100644 (file)
@@ -1,6 +1,8 @@
 package torrent
 
 import (
+       "context"
+       "errors"
        "fmt"
        "strings"
        "sync"
@@ -10,7 +12,6 @@ import (
        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) request(r Request) bool {
 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 @@ func (ws *webseedPeer) updateRequests() {
 }
 
 func (ws *webseedPeer) onClose() {
+       ws.peer.logger.Print("closing")
+       for _, r := range ws.activeRequests {
+               r.Cancel()
+       }
        ws.requesterCond.Broadcast()
 }
 
@@ -107,12 +114,14 @@ func (ws *webseedPeer) requestResultHandler(r Request, webseedRequest webseed.Re
        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)