]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Add counters for uploads
authorMatt Joiner <anacrolix@gmail.com>
Tue, 5 Jul 2016 05:52:33 +0000 (15:52 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Tue, 5 Jul 2016 05:52:33 +0000 (15:52 +1000)
Fixes #71.

client_test.go
conn_stats.go [new file with mode: 0644]
connection.go
torrent.go
torrent_stats.go [new file with mode: 0644]

index 6cefd18e669750965b76de9fdeb83f8c664f538b..648b55c20313a51cc50d0dbde693d9edc0b1da89 100644 (file)
@@ -306,6 +306,8 @@ type testClientTransferParams struct {
        SeederStorage                       func(string) storage.Client
 }
 
+// Creates a seeder and a leecher, and ensures the data transfers when a read
+// is attempted on the leecher.
 func testClientTransfer(t *testing.T, ps testClientTransferParams) {
        greetingTempDir, mi := testutil.GreetingTestTorrent()
        defer os.RemoveAll(greetingTempDir)
@@ -322,7 +324,7 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) {
        if ps.ExportClientStatus {
                testutil.ExportStatusWriter(seeder, "s")
        }
-       _, new, err := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
+       seederTorrent, new, err := seeder.AddTorrentSpec(TorrentSpecFromMetaInfo(mi))
        require.NoError(t, err)
        assert.True(t, new)
        leecherDataDir, err := ioutil.TempDir("", "")
@@ -362,14 +364,24 @@ func testClientTransfer(t *testing.T, ps testClientTransferParams) {
        if ps.SetReadahead {
                r.SetReadahead(ps.Readahead)
        }
-       for range iter.N(2) {
-               pos, err := r.Seek(0, os.SEEK_SET)
-               assert.NoError(t, err)
-               assert.EqualValues(t, 0, pos)
-               _greeting, err := ioutil.ReadAll(r)
-               assert.NoError(t, err)
-               assert.EqualValues(t, testutil.GreetingFileContents, _greeting)
-       }
+       assertReadAllGreeting(t, r)
+       // After one read through, we can assume certain torrent statistics.
+       assert.EqualValues(t, 13, seederTorrent.Stats().DataBytesSent)
+       assert.EqualValues(t, 8, seederTorrent.Stats().ChunksSent)
+       // This is not a strict requirement. It is however interesting to follow.
+       assert.EqualValues(t, 261, seederTorrent.Stats().BytesSent)
+       // Read through again for the cases where the torrent data size exceed the
+       // size of the cache.
+       assertReadAllGreeting(t, r)
+}
+
+func assertReadAllGreeting(t *testing.T, r io.ReadSeeker) {
+       pos, err := r.Seek(0, os.SEEK_SET)
+       assert.NoError(t, err)
+       assert.EqualValues(t, 0, pos)
+       _greeting, err := ioutil.ReadAll(r)
+       assert.NoError(t, err)
+       assert.EqualValues(t, testutil.GreetingFileContents, _greeting)
 }
 
 // Check that after completing leeching, a leecher transitions to a seeding
diff --git a/conn_stats.go b/conn_stats.go
new file mode 100644 (file)
index 0000000..5455b49
--- /dev/null
@@ -0,0 +1,23 @@
+package torrent
+
+import (
+       pp "github.com/anacrolix/torrent/peer_protocol"
+)
+
+type ConnStats struct {
+       ChunksSent    int64 // Num piece messages sent.
+       BytesSent     int64 // Total bytes sent.
+       DataBytesSent int64 // Data-only bytes sent.
+}
+
+func (cs *ConnStats) wroteMsg(msg pp.Message) {
+       switch msg.Type {
+       case pp.Piece:
+               cs.ChunksSent++
+               cs.DataBytesSent += int64(len(msg.Piece))
+       }
+}
+
+func (cs *ConnStats) wroteBytes(b []byte) {
+       cs.BytesSent += int64(len(b))
+}
index 3f0c4756d1986e7a5ab0a7ac7bc24c0dfa382d61..7f8e10b41d6254f87ffc0b723e0e0a0aa54b4e19 100644 (file)
@@ -44,6 +44,7 @@ type connection struct {
        uTP       bool
        closed    missinggo.Event
 
+       stats                  ConnStats
        UnwantedChunksReceived int
        UsefulChunksReceived   int
        chunksSent             int
@@ -425,6 +426,8 @@ func (cn *connection) writer(keepAliveTimeout time.Duration) {
                                panic("short write")
                        }
                        cn.mu().Lock()
+                       cn.wroteMsg(msg)
+                       cn.wroteBytes(b)
                }
                cn.outgoingUnbufferedMessagesNotEmpty.Clear()
                cn.mu().Unlock()
@@ -640,3 +643,13 @@ func (c *connection) requestPendingMetadata() {
                c.requestMetadataPiece(pending[i])
        }
 }
+
+func (cn *connection) wroteMsg(msg pp.Message) {
+       cn.stats.wroteMsg(msg)
+       cn.t.stats.wroteMsg(msg)
+}
+
+func (cn *connection) wroteBytes(b []byte) {
+       cn.stats.wroteBytes(b)
+       cn.t.stats.wroteBytes(b)
+}
index fa69665d6cc6bdecd8252bfeba4b0c9c92075cbd..6af85be70891e424599a426342b50e2a1df277cf 100644 (file)
@@ -93,6 +93,7 @@ type Torrent struct {
        completedPieces bitmap.Bitmap
 
        connPieceInclinationPool sync.Pool
+       stats                    TorrentStats
 }
 
 func (t *Torrent) setDisplayName(dn string) {
@@ -1268,3 +1269,7 @@ func (t *Torrent) addPeers(peers []Peer) {
                t.addPeer(p)
        }
 }
+
+func (t *Torrent) Stats() TorrentStats {
+       return t.stats
+}
diff --git a/torrent_stats.go b/torrent_stats.go
new file mode 100644 (file)
index 0000000..3f34434
--- /dev/null
@@ -0,0 +1,5 @@
+package torrent
+
+type TorrentStats struct {
+       ConnStats // Aggregates stats over all connections past and present.
+}