X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=webseed-peer.go;h=678c805bd9b3b4590aae11f5d92e0be86661d0ab;hb=92bba56b87fd06e3b0a5ea42862307718d8c4bd9;hp=4f4ca1f60eeadf9759862bf5c4b7f6f640d0f722;hpb=b5edd9ce8925b5efa5a8fb6c51c9e5c990f3ae48;p=btrtrc.git diff --git a/webseed-peer.go b/webseed-peer.go index 4f4ca1f6..678c805b 100644 --- a/webseed-peer.go +++ b/webseed-peer.go @@ -10,24 +10,33 @@ 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" ) +const ( + webseedPeerUnhandledErrorSleep = 5 * time.Second + webseedPeerCloseOnUnhandledError = false +) + type webseedPeer struct { - client webseed.Client - activeRequests map[Request]webseed.Request - requesterCond sync.Cond - peer Peer - // Number of requester routines. - maxRequests int + // First field for stats alignment. + peer Peer + client webseed.Client + activeRequests map[Request]webseed.Request + requesterCond sync.Cond + lastUnhandledErr time.Time } var _ peerImpl = (*webseedPeer)(nil) -func (me *webseedPeer) connStatusString() string { - return me.client.Url +func (me *webseedPeer) peerImplStatusLines() []string { + return []string{ + me.client.Url, + fmt.Sprintf("last unhandled error: %v", eventAgeString(me.lastUnhandledErr)), + } } func (ws *webseedPeer) String() string { @@ -84,8 +93,9 @@ func (ws *webseedPeer) requester(i int) { defer ws.requesterCond.L.Unlock() start: for !ws.peer.closed.IsSet() { + // Restart is set if we don't need to wait for the requestCond before trying again. restart := false - ws.peer.requestState.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 @@ -99,6 +109,7 @@ start: if errors.Is(err, webseed.ErrTooFast) { time.Sleep(time.Duration(rand.Int63n(int64(10 * time.Second)))) } + time.Sleep(time.Until(ws.lastUnhandledErr.Add(webseedPeerUnhandledErrorSleep))) ws.requesterCond.L.Lock() return false }) @@ -113,10 +124,13 @@ 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. @@ -167,8 +181,13 @@ func (ws *webseedPeer) requestResultHandler(r Request, webseedRequest webseed.Re // cfg := spew.NewDefaultConfig() // cfg.DisableMethods = true // cfg.Dump(result.Err) - log.Printf("closing %v", ws) - ws.peer.close() + + if webseedPeerCloseOnUnhandledError { + log.Printf("closing %v", ws) + ws.peer.close() + } else { + ws.lastUnhandledErr = time.Now() + } } if !ws.peer.remoteRejectedRequest(ws.peer.t.requestIndexFromRequest(r)) { panic("invalid reject")