panicif.Zero(key)
return cl.numWebSeedRequests[key] < defaultRequestsPerWebseedHost
}
-
-func (cl *Client) countWebSeedHttpRequests() (num int) {
- for t := range cl.torrents {
- for _, p := range t.webSeeds {
- num += p.numRequests()
- }
- }
- return
-}
// with legacy PeerConn methods. New methods and calls that are fixed up should be migrated over to
// newHotPeerImpl.
type legacyPeerImpl interface {
- // Trigger the actual request state to get updated
- handleOnNeedUpdateRequests()
- // Actually go ahead and modify the pending requests.
- updateRequests()
+ // Notify that the peers requests should be updated for the provided reason.
+ onNeedUpdateRequests(reason updateRequestReason)
// handleCancel initiates cancellation of a request
- handleCancel(RequestIndex)
- // The final piece to actually commit to a request. Typically, this sends or begins handling the
- // request.
- _request(Request) bool
+ handleCancel(ri RequestIndex)
connectionFlags() string
onClose()
- onGotInfo(*metainfo.Info)
+ onGotInfo(info *metainfo.Info)
// Drop connection. This may be a no-op if there is no connection.
drop()
// Rebuke the peer
ban()
String() string
+ // Per peer-impl lines for WriteStatus.
peerImplStatusLines() []string
// All if the peer should have everything, known if we know that for a fact. For example, we can
// Abstract methods implemented by subclasses of Peer.
type newHotPeerImpl interface {
lastWriteUploadRate() float64
+ // Bookkeeping for a chunk being received and any specific checks.
checkReceivedChunk(ri RequestIndex) error
+ // Whether we're expecting to receive chunks because we have outstanding requests. Used for
+ // example to calculate download rate.
expectingChunks() bool
}
for _, f := range cn.callbacks.SentRequest {
f(PeerRequestEvent{cn.peerPtr(), ppReq})
}
- return cn.legacyPeerImpl._request(ppReq), nil
+ return cn._request(ppReq), nil
}
func (me *Peer) cancel(r RequestIndex) {
}
// Sets a reason to update requests, and if there wasn't already one, handle it.
-func (cn *Peer) onNeedUpdateRequests(reason updateRequestReason) {
+func (cn *PeerConn) onNeedUpdateRequests(reason updateRequestReason) {
if cn.needRequestUpdate != "" {
return
}
})
}
+// The final piece to actually commit to a request. Typically, this sends or begins handling the
+// request.
func (me *PeerConn) _request(r Request) bool {
return me.write(pp.Message{
Type: pp.Request,
}
// Update requests if there's a reason assigned.
-func (p *Peer) maybeUpdateActualRequestState() {
+func (p *PeerConn) maybeUpdateActualRequestState() {
if p.needRequestUpdate == "" {
return
}
// Updates requests right now with the given reason. Clobbers any deferred reason if there was one.
// Does all the necessary checks and includes profiler tags to assign the overhead.
-func (p *Peer) updateRequestsWithReason(reason updateRequestReason) {
+func (p *PeerConn) updateRequestsWithReason(reason updateRequestReason) {
if p.closed.IsSet() {
return
}
return
}
t.iterPeers(func(c *Peer) {
- // if c.requestState.Interested {
- // return
- // }
if !c.isLowOnRequests() {
return
}
hostKey webseedHostKeyHandle
}
+// Webseed requests are issued globally so per-connection reasons or handling make no sense.
+func (me *webseedPeer) onNeedUpdateRequests(updateRequestReason) {}
+
func (me *webseedPeer) expectingChunks() bool {
return len(me.activeRequests) > 0
}
return len(me.activeRequests)
}
-func (me *webseedPeer) shouldUpdateRequests() bool {
- return me.moreRequestsAllowed()
-}
-
-func (me *webseedPeer) moreRequestsAllowed() bool {
- return me.numRequests() < me.client.MaxRequests && me.peer.t.cl.underWebSeedHttpRequestLimit(me.hostKey)
-}
-
-func (me *webseedPeer) updateRequests() {
- return
-}
-
func (me *webseedPeer) lastWriteUploadRate() float64 {
// We never upload to webseeds.
return 0
return webseed.RequestSpec{start, endOff - start}
}
-func (ws *webseedPeer) _request(r Request) bool {
- return true
-}
-
func (ws *webseedPeer) spawnRequest(begin, end RequestIndex) {
extWsReq := ws.client.StartNewRequest(ws.intoSpec(begin, end))
wsReq := webseedRequest{
ws.peer.updateExpectingChunks()
}
-func (ws *webseedPeer) spawnRequests() {
- next, stop := iter.Pull(ws.inactiveRequests())
- defer stop()
- for ws.moreRequestsAllowed() {
- req, ok := next()
- if !ok {
- break
- }
- end := seqLast(ws.iterConsecutiveInactiveRequests(req)).Unwrap()
- ws.spawnRequest(req, end+1)
- }
-}
-
func (ws *webseedPeer) iterConsecutiveRequests(begin RequestIndex) iter.Seq[RequestIndex] {
return func(yield func(RequestIndex) bool) {
for {
cn.peer.close()
}
-func (ws *webseedPeer) handleOnNeedUpdateRequests() {
- ws.peer.maybeUpdateActualRequestState()
-}
-
func (ws *webseedPeer) onClose() {
// Just deleting them means we would have to manually cancel active requests.
ws.peer.cancelAllRequests()