X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=peer.go;h=cf79b79969a0582e215f120f7228e4805b2f1f7f;hb=refs%2Fheads%2Fbtrtrc;hp=733aa018ef29727d10df21a44e5f3aa54e033cfb;hpb=bcd7fd4a6d83f4aca1e9e3d4c35997ef6aca405d;p=btrtrc.git diff --git a/peer.go b/peer.go index 733aa018..d6fdd02f 100644 --- a/peer.go +++ b/peer.go @@ -6,7 +6,6 @@ import ( "io" "net" "strings" - "sync" "time" "github.com/RoaringBitmap/roaring" @@ -225,9 +224,9 @@ func (cn *Peer) statusFlags() (ret string) { if cn.choking { c('c') } - c(':') + c('-') ret += cn.connectionFlags() - c(':') + c('-') if cn.peerInterested { c('i') } @@ -237,6 +236,10 @@ func (cn *Peer) statusFlags() (ret string) { return } +func (cn *Peer) StatusFlags() string { + return cn.statusFlags() +} + func (cn *Peer) downloadRate() float64 { num := cn._stats.BytesReadUsefulData.Int64() if num == 0 { @@ -245,11 +248,21 @@ func (cn *Peer) downloadRate() float64 { return float64(num) / cn.totalExpectingTime().Seconds() } -func (p *Peer) DownloadRate() float64 { - p.locker().RLock() - defer p.locker().RUnlock() +func (cn *Peer) DownloadRate() float64 { + cn.locker().RLock() + defer cn.locker().RUnlock() - return p.downloadRate() + return cn.downloadRate() +} + +func (cn *Peer) UploadRate() float64 { + cn.locker().RLock() + defer cn.locker().RUnlock() + num := cn._stats.BytesWrittenData.Int64() + if num == 0 { + return 0 + } + return float64(num) / time.Now().Sub(cn.completedHandshake).Seconds() } func (cn *Peer) iterContiguousPieceRequests(f func(piece pieceIndex, count int)) { @@ -334,13 +347,6 @@ func (p *Peer) close() { } } -func (p *Peer) Close() error { - p.locker().Lock() - defer p.locker().Unlock() - p.close() - return nil -} - // Peer definitely has a piece, for purposes of requesting. So it's not sufficient that we think // they do (known=true). func (cn *Peer) peerHasPiece(piece pieceIndex) bool { @@ -473,7 +479,6 @@ func (me *Peer) cancel(r RequestIndex) { panic("request not existing should have been guarded") } if me._cancel(r) { - // Record that we expect to get a cancel ack. if !me.requestState.Cancelled.CheckedAdd(r) { panic("request already cancelled") } @@ -489,6 +494,9 @@ func (cn *Peer) updateRequests(reason string) { if cn.needRequestUpdate != "" { return } + if reason != peerUpdateRequestsTimerReason && !cn.isLowOnRequests() { + return + } cn.needRequestUpdate = reason cn.handleUpdateRequests() } @@ -534,6 +542,14 @@ func (cn *Peer) allStats(f func(*ConnStats)) { } } +func (cn *Peer) Stats() *ConnStats { + return cn.stats() +} + +func (cn *Peer) CompletedString() string { + return cn.completedString() +} + func (cn *Peer) readBytes(n int64) { cn.allStats(add(n, func(cs *ConnStats) *Count { return &cs.BytesRead })) } @@ -608,13 +624,9 @@ func (c *Peer) receiveChunk(msg *pp.Message) error { } req := c.t.requestIndexFromRequest(ppReq) - recordBlockForSmartBan := sync.OnceFunc(func() { - c.recordBlockForSmartBan(req, msg.Piece) - }) - // This needs to occur before we return, but we try to do it when the client is unlocked. It - // can't be done before checking if chunks are valid because they won't be deallocated by piece - // hashing if they're out of bounds. - defer recordBlockForSmartBan() + if c.bannableAddr.Ok { + t.smartBanCache.RecordBlock(c.bannableAddr.Value, req, msg.Piece) + } if c.peerChoking { chunksReceived.Add("while choked", 1) @@ -695,8 +707,6 @@ func (c *Peer) receiveChunk(msg *pp.Message) error { err = func() error { cl.unlock() defer cl.lock() - // Opportunistically do this here while we aren't holding the client lock. - recordBlockForSmartBan() concurrentChunkWrites.Add(1) defer concurrentChunkWrites.Add(-1) // Write the chunk out. Note that the upper bound on chunk writing concurrency will be the @@ -733,7 +743,7 @@ func (c *Peer) receiveChunk(msg *pp.Message) error { cl.event.Broadcast() // We do this because we've written a chunk, and may change PieceState.Partial. - t.publishPieceStateChange(pieceIndex(ppReq.Index)) + t.publishPieceChange(pieceIndex(ppReq.Index)) return nil } @@ -889,9 +899,3 @@ func (p *Peer) decPeakRequests() { // } p.peakRequests-- } - -func (p *Peer) recordBlockForSmartBan(req RequestIndex, blockData []byte) { - if p.bannableAddr.Ok { - p.t.smartBanCache.RecordBlock(p.bannableAddr.Value, req, blockData) - } -}