]> Sergey Matveev's repositories - btrtrc.git/blobdiff - webseed-peer.go
Rename tracker/http package
[btrtrc.git] / webseed-peer.go
index cfce1e81d4b2768b9264340f28586c21b6ce2c7d..52e33c721217b51096a5d6e99c6f179233c5e23c 100644 (file)
@@ -10,16 +10,18 @@ import (
 
        "github.com/RoaringBitmap/roaring"
        "github.com/anacrolix/log"
+
        "github.com/anacrolix/torrent/metainfo"
        pp "github.com/anacrolix/torrent/peer_protocol"
        "github.com/anacrolix/torrent/webseed"
 )
 
 type webseedPeer struct {
+       // First field for stats alignment.
+       peer           Peer
        client         webseed.Client
        activeRequests map[Request]webseed.Request
        requesterCond  sync.Cond
-       peer           Peer
        // Number of requester routines.
        maxRequests int
 }
@@ -49,17 +51,13 @@ func (ws *webseedPeer) writeInterested(interested bool) bool {
 }
 
 func (ws *webseedPeer) _cancel(r RequestIndex) bool {
-       active, ok := ws.activeRequests[ws.peer.t.requestIndexToRequest(r)]
-       if ok {
+       if active, ok := ws.activeRequests[ws.peer.t.requestIndexToRequest(r)]; ok {
                active.Cancel()
+               // The requester is running and will handle the result.
+               return true
        }
-       if !ws.peer.deleteRequest(r) {
-               panic("cancelled webseed request should exist")
-       }
-       if ws.peer.isLowOnRequests() {
-               ws.peer.updateRequests("webseedPeer._cancel")
-       }
-       return true
+       // There should be no requester handling this, so no further events will occur.
+       return false
 }
 
 func (ws *webseedPeer) intoSpec(r Request) webseed.RequestSpec {
@@ -89,7 +87,7 @@ func (ws *webseedPeer) requester(i int) {
 start:
        for !ws.peer.closed.IsSet() {
                restart := false
-               ws.peer.actualRequestState.Requests.Iterate(func(x uint32) bool {
+               ws.peer.requestState.Requests.Iterate(func(x RequestIndex) bool {
                        r := ws.peer.t.requestIndexToRequest(x)
                        if _, ok := ws.activeRequests[r]; ok {
                                return true
@@ -117,22 +115,32 @@ func (ws *webseedPeer) connectionFlags() string {
        return "WS"
 }
 
-// TODO: This is called when banning peers. Perhaps we want to be able to ban webseeds too. We could
-// return bool if this is even possible, and if it isn't, skip to the next drop candidate.
+// Maybe this should drop all existing connections, or something like that.
 func (ws *webseedPeer) drop() {}
 
+func (cn *webseedPeer) ban() {
+       cn.peer.close()
+}
+
 func (ws *webseedPeer) handleUpdateRequests() {
        // Because this is synchronous, webseed peers seem to get first dibs on newly prioritized
        // pieces.
-       ws.peer.maybeUpdateActualRequestState()
+       go func() {
+               ws.peer.t.cl.lock()
+               defer ws.peer.t.cl.unlock()
+               ws.peer.maybeUpdateActualRequestState()
+       }()
 }
 
 func (ws *webseedPeer) onClose() {
-       ws.peer.logger.WithLevel(log.Debug).Print("closing")
-       ws.peer.deleteAllRequests()
-       for _, r := range ws.activeRequests {
-               r.Cancel()
-       }
+       ws.peer.logger.Levelf(log.Debug, "closing")
+       // Just deleting them means we would have to manually cancel active requests.
+       ws.peer.cancelAllRequests()
+       ws.peer.t.iterPeers(func(p *Peer) {
+               if p.isLowOnRequests() {
+                       p.updateRequests("webseedPeer.onClose")
+               }
+       })
        ws.requesterCond.Broadcast()
 }
 
@@ -167,7 +175,9 @@ func (ws *webseedPeer) requestResultHandler(r Request, webseedRequest webseed.Re
                        log.Printf("closing %v", ws)
                        ws.peer.close()
                }
-               ws.peer.remoteRejectedRequest(ws.peer.t.requestIndexFromRequest(r))
+               if !ws.peer.remoteRejectedRequest(ws.peer.t.requestIndexFromRequest(r)) {
+                       panic("invalid reject")
+               }
                return err
        }
        err = ws.peer.receiveChunk(&pp.Message{
@@ -182,10 +192,6 @@ func (ws *webseedPeer) requestResultHandler(r Request, webseedRequest webseed.Re
        return err
 }
 
-func (me *webseedPeer) isLowOnRequests() bool {
-       return me.peer.actualRequestState.Requests.GetCardinality() < uint64(me.maxRequests)
-}
-
 func (me *webseedPeer) peerPieces() *roaring.Bitmap {
        return &me.client.Pieces
 }