go.mod | 2 +- go.sum | 4 ++-- storage/issue96_test.go | 2 +- storage/piece-resource.go | 25 +++++++++++++++++++------ storage/possum/possum_test.go | 8 +++++++- diff --git a/go.mod b/go.mod index 1af03a6edd73e57be5e46847b734f93afd61927e..51402c253d78d77aa68fb87cd2659dcbfb12428a 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ github.com/anacrolix/missinggo v1.3.0 github.com/anacrolix/missinggo/perf v1.0.0 github.com/anacrolix/missinggo/v2 v2.7.3 github.com/anacrolix/multiless v0.3.0 - github.com/anacrolix/possum/go v0.0.0-20240222034319-2fe0737d4315 + github.com/anacrolix/possum/go v0.1.1-0.20240309232535-7d660fa365f8 github.com/anacrolix/squirrel v0.6.0 github.com/anacrolix/sync v0.5.1 github.com/anacrolix/tagflag v1.3.0 diff --git a/go.sum b/go.sum index fb5f86b14f10b09ab79cce4838e8b88ab583242b..0834ba1b947d37b6a467065e74700b41ed940162 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,8 @@ github.com/anacrolix/mmsg v1.0.0 h1:btC7YLjOn29aTUAExJiVUhQOuf/8rhm+/nWCMAnL3Hg= github.com/anacrolix/mmsg v1.0.0/go.mod h1:x8kRaJY/dCrY9Al0PEcj1mb/uFHwP6GCJ9fLl4thEPc= github.com/anacrolix/multiless v0.3.0 h1:5Bu0DZncjE4e06b9r1Ap2tUY4Au0NToBP5RpuEngSis= github.com/anacrolix/multiless v0.3.0/go.mod h1:TrCLEZfIDbMVfLoQt5tOoiBS/uq4y8+ojuEVVvTNPX4= -github.com/anacrolix/possum/go v0.0.0-20240222034319-2fe0737d4315 h1:bwdpi8LWvEHrNgsu44SKmCzLeZ5iEH4rwmNafDdRHJ4= -github.com/anacrolix/possum/go v0.0.0-20240222034319-2fe0737d4315/go.mod h1:pw5HEMBSiL+otYzHe4q5jGaVuy5unl+Mt4Bx6SDemW8= +github.com/anacrolix/possum/go v0.1.1-0.20240309232535-7d660fa365f8 h1:XDKUI9RHyhyfGXVXb/4N+l5kGo5jQITrrbF7EZPLuak= +github.com/anacrolix/possum/go v0.1.1-0.20240309232535-7d660fa365f8/go.mod h1:pw5HEMBSiL+otYzHe4q5jGaVuy5unl+Mt4Bx6SDemW8= github.com/anacrolix/squirrel v0.6.0 h1:ovfWW42wcGzrVYYI9s56pEYzfeTwtXxCCvSd+KwvUEA= github.com/anacrolix/squirrel v0.6.0/go.mod h1:60vdNPUbK1jYWePp39Wqn9whHm12Yb9JEuwOXzLMDuY= github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg= diff --git a/storage/issue96_test.go b/storage/issue96_test.go index 1be98aa5e738cd8976e7587d96759638175be916..d9857881a7c0a8d6a8b0a963e0710920859e1251 100644 --- a/storage/issue96_test.go +++ b/storage/issue96_test.go @@ -1,9 +1,9 @@ package storage import ( - g "github.com/anacrolix/generics" "testing" + g "github.com/anacrolix/generics" "github.com/stretchr/testify/require" "github.com/anacrolix/torrent/metainfo" diff --git a/storage/piece-resource.go b/storage/piece-resource.go index 94325027b047a27f52f25e9d5871b3a3e04d4aa1..1b0ae236a5f3c633afd7f95020eac046ec02045c 100644 --- a/storage/piece-resource.go +++ b/storage/piece-resource.go @@ -75,6 +75,10 @@ type ConsecutiveChunkReader interface { ReadConsecutiveChunks(prefix string) (io.ReadCloser, error) } +type PrefixDeleter interface { + DeletePrefix(prefix string) error +} + type piecePerResourcePiece struct { mp metainfo.Piece // The piece hash if we have it. It could be 20 or 32 bytes depending on the info version. @@ -140,7 +144,7 @@ type SizedPutter interface { PutSized(io.Reader, int64) error } -func (s piecePerResourcePiece) MarkComplete() error { +func (s piecePerResourcePiece) MarkComplete() (err error) { s.mu.Lock() defer s.mu.Unlock() incompleteChunks := s.getChunks() @@ -162,11 +166,20 @@ } else { return completedInstance.Put(r) } }() - if err == nil && !s.opts.LeaveIncompleteChunks { - // I think we do this synchronously here since we don't want callers to act on the completed - // piece if we're concurrently still deleting chunks. The caller may decide to start - // downloading chunks again and won't expect us to delete them. It seems to be much faster - // to let the resource provider do this if possible. + if err != nil || s.opts.LeaveIncompleteChunks { + return + } + + // I think we do this synchronously here since we don't want callers to act on the completed + // piece if we're concurrently still deleting chunks. The caller may decide to start + // downloading chunks again and won't expect us to delete them. It seems to be much faster + // to let the resource provider do this if possible. + if pd, ok := s.rp.(PrefixDeleter); ok { + err = pd.DeletePrefix(s.incompleteDirPath() + "/") + if err != nil { + err = fmt.Errorf("deleting incomplete prefix: %w", err) + } + } else { var wg sync.WaitGroup for _, c := range incompleteChunks { wg.Add(1) diff --git a/storage/possum/possum_test.go b/storage/possum/possum_test.go index 1c0e81105db25851e47c43649495e2e397569337..3abefd49332d557163a2f24fa509c517ccf7f666 100644 --- a/storage/possum/possum_test.go +++ b/storage/possum/possum_test.go @@ -28,5 +28,11 @@ possumTorrentProvider := Provider{Provider: possumProvider, Logger: log.Default} clientStorageImpl := storage.NewResourcePiecesOpts( possumTorrentProvider, storage.ResourcePiecesOpts{LeaveIncompleteChunks: true}) - test_storage.BenchmarkPieceMarkComplete(b, clientStorageImpl, test_storage.DefaultPieceSize, test_storage.DefaultNumPieces, 0) + test_storage.BenchmarkPieceMarkComplete( + b, + clientStorageImpl, + test_storage.DefaultPieceSize, + test_storage.DefaultNumPieces, + 0, + ) }