From e6da640bb2b5de5ff43689cdbc517125976b8073 Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 9 Nov 2020 10:56:27 +1100 Subject: [PATCH] Tidy up doc, file names, naming --- client.go | 12 ++--- cmd/tracker-announce/main.go | 2 +- config.go | 2 +- metainfo/magnet.go | 4 +- metainfo/magnet_test.go | 12 ++--- piece.go | 2 + reader.go | 44 +++++++++---------- ...efaults.go => request-strategy-defaults.go | 0 request_strategy.go => request-strategy.go | 11 ++--- socket.go | 7 ++- spec.go | 4 +- torrent.go | 4 ++ util/dirwatch/dirwatch.go | 2 +- 13 files changed, 57 insertions(+), 49 deletions(-) rename request_strategy_defaults.go => request-strategy-defaults.go (100%) rename request_strategy.go => request-strategy.go (94%) diff --git a/client.go b/client.go index c4e3e6b0..8dce3d40 100644 --- a/client.go +++ b/client.go @@ -455,7 +455,7 @@ func (cl *Client) rejectAccepted(conn net.Conn) error { return nil } -func (cl *Client) acceptConnections(l net.Listener) { +func (cl *Client) acceptConnections(l Listener) { for { conn, err := l.Accept() torrent.Add("client listener accepts", 1) @@ -1178,7 +1178,7 @@ func (t *Torrent) MergeSpec(spec *TorrentSpec) error { } } cl := t.cl - cl.AddDHTNodes(spec.DhtNodes) + cl.AddDhtNodes(spec.DhtNodes) cl.lock() defer cl.unlock() useTorrentSources(spec.Sources, t) @@ -1293,7 +1293,7 @@ func (cl *Client) torrentsAsSlice() (ret []*Torrent) { } func (cl *Client) AddMagnet(uri string) (T *Torrent, err error) { - spec, err := TorrentSpecFromMagnetURI(uri) + spec, err := TorrentSpecFromMagnetUri(uri) if err != nil { return } @@ -1318,7 +1318,7 @@ func (cl *Client) DhtServers() []DhtServer { return cl.dhtServers } -func (cl *Client) AddDHTNodes(nodes []string) { +func (cl *Client) AddDhtNodes(nodes []string) { for _, n := range nodes { hmp := missinggo.SplitHostMaybePort(n) ip := net.ParseIP(hmp.Host) @@ -1412,7 +1412,7 @@ func (cl *Client) eachListener(f func(Listener) bool) { } } -func (cl *Client) findListener(f func(net.Listener) bool) (ret net.Listener) { +func (cl *Client) findListener(f func(Listener) bool) (ret Listener) { cl.eachListener(func(l Listener) bool { ret = l return !f(l) @@ -1437,7 +1437,7 @@ func (cl *Client) publicIp(peer net.IP) net.IP { func (cl *Client) findListenerIp(f func(net.IP) bool) net.IP { l := cl.findListener( - func(l net.Listener) bool { + func(l Listener) bool { return f(addrIpOrNil(l.Addr())) }, ) diff --git a/cmd/tracker-announce/main.go b/cmd/tracker-announce/main.go index 8d9681dd..86777a66 100644 --- a/cmd/tracker-announce/main.go +++ b/cmd/tracker-announce/main.go @@ -18,7 +18,7 @@ import ( func argSpec(arg string) (ts *torrent.TorrentSpec, err error) { if strings.HasPrefix(arg, "magnet:") { - return torrent.TorrentSpecFromMagnetURI(arg) + return torrent.TorrentSpecFromMagnetUri(arg) } mi, err := metainfo.LoadFromFile(arg) if err != nil { diff --git a/config.go b/config.go index 4af86cf6..afc43469 100644 --- a/config.go +++ b/config.go @@ -128,7 +128,7 @@ type ClientConfig struct { // OnQuery hook func DHTOnQuery func(query *krpc.Msg, source net.Addr) (propagate bool) - DefaultRequestStrategy RequestStrategyMaker + DefaultRequestStrategy requestStrategyMaker Extensions PeerExtensionBits diff --git a/metainfo/magnet.go b/metainfo/magnet.go index 9fd15c6b..e707762e 100644 --- a/metainfo/magnet.go +++ b/metainfo/magnet.go @@ -46,8 +46,8 @@ func (m Magnet) String() string { return u.String() } -// ParseMagnetURI parses Magnet-formatted URIs into a Magnet instance -func ParseMagnetURI(uri string) (m Magnet, err error) { +// ParseMagnetUri parses Magnet-formatted URIs into a Magnet instance +func ParseMagnetUri(uri string) (m Magnet, err error) { u, err := url.Parse(uri) if err != nil { err = fmt.Errorf("error parsing uri: %w", err) diff --git a/metainfo/magnet_test.go b/metainfo/magnet_test.go index d75f3679..e11abf6e 100644 --- a/metainfo/magnet_test.go +++ b/metainfo/magnet_test.go @@ -25,7 +25,7 @@ func init() { // Converting from our Magnet type to URL string. func TestMagnetString(t *testing.T) { - m, err := ParseMagnetURI(exampleMagnet.String()) + m, err := ParseMagnetUri(exampleMagnet.String()) require.NoError(t, err) assert.EqualValues(t, exampleMagnet, m) } @@ -37,18 +37,18 @@ func TestParseMagnetURI(t *testing.T) { // parsing the legit Magnet URI with btih-formatted xt should not return errors uri = "magnet:?xt=urn:btih:ZOCMZQIPFFW7OLLMIC5HUB6BPCSDEOQU" - _, err = ParseMagnetURI(uri) + _, err = ParseMagnetUri(uri) if err != nil { t.Errorf("Attempting parsing the proper Magnet btih URI:\"%v\" failed with err: %v", uri, err) } // Checking if the magnet instance struct is built correctly from parsing - m, err = ParseMagnetURI(exampleMagnetURI) + m, err = ParseMagnetUri(exampleMagnetURI) assert.EqualValues(t, exampleMagnet, m) assert.NoError(t, err) // empty string URI case - _, err = ParseMagnetURI("") + _, err = ParseMagnetUri("") if err == nil { t.Errorf("Parsing empty string as URI should have returned an error but didn't") } @@ -56,14 +56,14 @@ func TestParseMagnetURI(t *testing.T) { // only BTIH (BitTorrent info hash)-formatted magnet links are currently supported // must return error correctly when encountering other URN formats uri = "magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C" - _, err = ParseMagnetURI(uri) + _, err = ParseMagnetUri(uri) if err == nil { t.Errorf("Magnet URI with non-BTIH URNs (like \"%v\") are not supported and should return an error", uri) } // resilience to the broken hash uri = "magnet:?xt=urn:btih:this hash is really broken" - _, err = ParseMagnetURI(uri) + _, err = ParseMagnetUri(uri) if err == nil { t.Errorf("Failed to detect broken Magnet URI: %v", uri) } diff --git a/piece.go b/piece.go index 56dedec6..08fc9bab 100644 --- a/piece.go +++ b/piece.go @@ -240,6 +240,8 @@ func (p *Piece) uncachedPriority() (ret piecePriority) { return } +// Tells the Client to refetch the completion status from storage, updating priority etc. if +// necessary. Might be useful if you know the state of the piece data has changed externally. func (p *Piece) UpdateCompletion() { p.t.cl.lock() defer p.t.cl.unlock() diff --git a/reader.go b/reader.go index 8610910d..965fbdf8 100644 --- a/reader.go +++ b/reader.go @@ -11,12 +11,18 @@ import ( "github.com/anacrolix/missinggo" ) +// Accesses Torrent data via a Client. Reads block until the data is available. Seeks and readahead +// also drive Client behaviour. type Reader interface { io.Reader io.Seeker io.Closer missinggo.ReadContexter + // Configure the number of bytes ahead of a read that should also be prioritized in preparation + // for further reads. SetReadahead(int64) + // Don't wait for pieces to complete and be verified. Read calls return as soon as they can when + // the underlying chunks become available. SetResponsive() } @@ -25,33 +31,26 @@ type pieceRange struct { begin, end pieceIndex } -// Accesses Torrent data via a Client. Reads block until the data is -// available. Seeks and readahead also drive Client behaviour. type reader struct { t *Torrent responsive bool - // Adjust the read/seek window to handle Readers locked to File extents - // and the like. + // Adjust the read/seek window to handle Readers locked to File extents and the like. offset, length int64 - // Ensure operations that change the position are exclusive, like Read() - // and Seek(). + // Ensure operations that change the position are exclusive, like Read() and Seek(). opMu sync.Mutex - // Required when modifying pos and readahead, or reading them without - // opMu. + // Required when modifying pos and readahead, or reading them without opMu. mu sync.Locker pos int64 readahead int64 - // The cached piece range this reader wants downloaded. The zero value - // corresponds to nothing. We cache this so that changes can be detected, - // and bubbled up to the Torrent only as required. + // The cached piece range this reader wants downloaded. The zero value corresponds to nothing. + // We cache this so that changes can be detected, and bubbled up to the Torrent only as + // required. pieces pieceRange } -var _ io.ReadCloser = &reader{} +var _ io.ReadCloser = (*reader)(nil) -// Don't wait for pieces to complete and be verified. Read calls return as -// soon as they can when the underlying chunks become available. func (r *reader) SetResponsive() { r.responsive = true r.t.cl.event.Broadcast() @@ -63,8 +62,6 @@ func (r *reader) SetNonResponsive() { r.t.cl.event.Broadcast() } -// Configure the number of bytes ahead of a read that should also be -// prioritized in preparation for further reads. func (r *reader) SetReadahead(readahead int64) { r.mu.Lock() r.readahead = readahead @@ -101,13 +98,11 @@ func (r *reader) available(off, max int64) (ret int64) { } func (r *reader) waitReadable(off int64) { - // We may have been sent back here because we were told we could read but - // it failed. + // We may have been sent back here because we were told we could read but it failed. r.t.cl.event.Wait() } -// Calculates the pieces this reader wants downloaded, ignoring the cached -// value at r.pieces. +// Calculates the pieces this reader wants downloaded, ignoring the cached value at r.pieces. func (r *reader) piecesUncached() (ret pieceRange) { ra := r.readahead if ra < 1 { @@ -143,8 +138,8 @@ func (r *reader) ReadContext(ctx context.Context, b []byte) (n int, err error) { r.t.cl.unlock() }() } - // Hmmm, if a Read gets stuck, this means you can't change position for - // other purposes. That seems reasonable, but unusual. + // Hmmm, if a Read gets stuck, this means you can't change position for other purposes. That + // seems reasonable, but unusual. r.opMu.Lock() defer r.opMu.Unlock() n, err = r.readOnceAt(b, r.pos, &ctxErr) @@ -168,8 +163,8 @@ func (r *reader) ReadContext(ctx context.Context, b []byte) (n int, err error) { return } -// Wait until some data should be available to read. Tickles the client if it -// isn't. Returns how much should be readable without blocking. +// Wait until some data should be available to read. Tickles the client if it isn't. Returns how +// much should be readable without blocking. func (r *reader) waitAvailable(pos, wanted int64, ctxErr *error, wait bool) (avail int64, err error) { r.t.cl.lock() defer r.t.cl.unlock() @@ -244,6 +239,7 @@ func (r *reader) readOnceAt(b []byte, pos int64, ctxErr *error) (n int, err erro } } +// Hodor func (r *reader) Close() error { r.t.cl.lock() defer r.t.cl.unlock() diff --git a/request_strategy_defaults.go b/request-strategy-defaults.go similarity index 100% rename from request_strategy_defaults.go rename to request-strategy-defaults.go diff --git a/request_strategy.go b/request-strategy.go similarity index 94% rename from request_strategy.go rename to request-strategy.go index 341d84ad..2cb03bac 100644 --- a/request_strategy.go +++ b/request-strategy.go @@ -67,17 +67,17 @@ type requestStrategyFastest struct { requestStrategyDefaults } -func newRequestStrategyMaker(rs requestStrategy) RequestStrategyMaker { +func newRequestStrategyMaker(rs requestStrategy) requestStrategyMaker { return func(requestStrategyCallbacks, sync.Locker) requestStrategy { return rs } } -func RequestStrategyFastest() RequestStrategyMaker { +func RequestStrategyFastest() requestStrategyMaker { return newRequestStrategyMaker(requestStrategyFastest{}) } -func RequestStrategyFuzzing() RequestStrategyMaker { +func RequestStrategyFuzzing() requestStrategyMaker { return newRequestStrategyMaker(requestStrategyFuzzing{}) } @@ -110,9 +110,10 @@ type requestStrategyDuplicateRequestTimeout struct { timeoutLocker sync.Locker } -type RequestStrategyMaker func(callbacks requestStrategyCallbacks, clientLocker sync.Locker) requestStrategy +// Generates a request strategy instance for a given torrent. callbacks are probably specific to the torrent. +type requestStrategyMaker func(callbacks requestStrategyCallbacks, clientLocker sync.Locker) requestStrategy -func RequestStrategyDuplicateRequestTimeout(duplicateRequestTimeout time.Duration) RequestStrategyMaker { +func RequestStrategyDuplicateRequestTimeout(duplicateRequestTimeout time.Duration) requestStrategyMaker { return func(callbacks requestStrategyCallbacks, clientLocker sync.Locker) requestStrategy { return requestStrategyDuplicateRequestTimeout{ duplicateRequestTimeout: duplicateRequestTimeout, diff --git a/socket.go b/socket.go index 1ae4b42f..d9654ace 100644 --- a/socket.go +++ b/socket.go @@ -11,12 +11,17 @@ import ( ) type Listener interface { - net.Listener + // Accept waits for and returns the next connection to the listener. + Accept() (net.Conn, error) + + // Addr returns the listener's network address. + Addr() net.Addr } type socket interface { Listener Dialer + Close() error } func listen(n network, addr string, f firewallCallback) (socket, error) { diff --git a/spec.go b/spec.go index b5007c26..0818a99c 100644 --- a/spec.go +++ b/spec.go @@ -28,8 +28,8 @@ type TorrentSpec struct { DisallowDataDownload bool } -func TorrentSpecFromMagnetURI(uri string) (spec *TorrentSpec, err error) { - m, err := metainfo.ParseMagnetURI(uri) +func TorrentSpecFromMagnetUri(uri string) (spec *TorrentSpec, err error) { + m, err := metainfo.ParseMagnetUri(uri) if err != nil { return } diff --git a/torrent.go b/torrent.go index ced35bb7..38c92ee9 100644 --- a/torrent.go +++ b/torrent.go @@ -2043,6 +2043,7 @@ func (t *Torrent) AllowDataDownload() { }) } +// Enables uploading data, if it was disabled. func (t *Torrent) AllowDataUpload() { t.cl.lock() defer t.cl.unlock() @@ -2052,6 +2053,7 @@ func (t *Torrent) AllowDataUpload() { } } +// Disables uploading data, if it was enabled. func (t *Torrent) DisallowDataUpload() { t.cl.lock() defer t.cl.unlock() @@ -2061,6 +2063,8 @@ func (t *Torrent) DisallowDataUpload() { } } +// Sets a handler that is called if there's an error writing a chunk to local storage. By default, +// or if nil, a critical message is logged, and data download is disabled. func (t *Torrent) SetOnWriteChunkError(f func(error)) { t.cl.lock() defer t.cl.unlock() diff --git a/util/dirwatch/dirwatch.go b/util/dirwatch/dirwatch.go index 018d3f42..3e0e910a 100644 --- a/util/dirwatch/dirwatch.go +++ b/util/dirwatch/dirwatch.go @@ -116,7 +116,7 @@ func scanDir(dirName string) (ee map[metainfo.Hash]entity) { break } for _, uri := range uris { - m, err := metainfo.ParseMagnetURI(uri) + m, err := metainfo.ParseMagnetUri(uri) if err != nil { log.Printf("error parsing %q in file %q: %s", uri, fullName, err) continue -- 2.44.0