}
}
cl.defaultLocalLtepProtocolMap = makeBuiltinLtepProtocols(!cfg.DisablePEX)
+ g.MakeMap(&cl.numWebSeedRequests)
}
// Creates a new Client. Takes ownership of the ClientConfig. Create another one if you want another
func (ws *webseedPeer) handleCancel(r RequestIndex) {
for wr := range ws.activeRequestsForIndex(r) {
- wr.request.Cancel()
+ wr.Cancel()
}
}
locker := ws.locker
err := ws.readChunks(webseedRequest)
// Ensure the body reader and response are closed.
- webseedRequest.request.Cancel()
+ webseedRequest.Close()
if err != nil {
- level := slog.LevelWarn
- if errors.Is(err, context.Canceled) {
+ level := slog.LevelInfo
+ if webseedRequest.cancelled {
level = slog.LevelDebug
}
ws.slogger().Log(context.TODO(), level, "webseed request error", "err", err)
+ torrent.Add("webseed request error count", 1)
// This used to occur only on webseed.ErrTooFast but I think it makes sense to slow down any
// kind of error. Pausing here will starve the available requester slots which slows things
// down.
// A wrapper around webseed.Request with extra state for webseedPeer.
type webseedRequest struct {
+ // Fingers out.
request webseed.Request
// First assigned in the range.
begin RequestIndex
// The next to be read.
next RequestIndex
// One greater than the end of the range.
- end RequestIndex
+ end RequestIndex
+ cancelled bool
+}
+
+func (me *webseedRequest) Close() {
+ me.request.Cancel()
+}
+
+// Record that it was exceptionally cancelled.
+func (me *webseedRequest) Cancel() {
+ me.cancelled = true
+ me.request.Cancel()
}