Skip to content

Commit 3dd683c

Browse files
committed
Close shared readers when storage is closed
1 parent 860a5b7 commit 3dd683c

File tree

4 files changed

+43
-37
lines changed

4 files changed

+43
-37
lines changed

justfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ act:
88

99
export GOPPROF := env("GOPPROF", "http")
1010

11-
test-short: build-possum
12-
GOPPROF='{{GOPPROF}}' go test -race -failfast -short ./...
11+
test-short *args: build-possum
12+
GOPPROF='{{GOPPROF}}' go test -race -failfast -short {{ args }} ./...
1313

1414
test *args: build-possum
1515
go test -race {{ args }} ./...

storage/file-io-classic.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ import (
77

88
type classicFileIo struct{}
99

10+
// Lifetimes of files are scoped to their use, so let's hope everyone is being a good citizen.
11+
func (me classicFileIo) Close() error {
12+
return nil
13+
}
14+
1015
func (me classicFileIo) rename(from, to string) error {
1116
return os.Rename(from, to)
1217
}

storage/file-io.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ var defaultFileIo = func() fileIo {
2222
}
2323

2424
type fileIo interface {
25+
Close() error
2526

2627
openForSharedRead(name string) (sharableReader, error)
2728
openForRead(name string) (fileReader, error)

storage/file-torrent.go

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -26,38 +26,38 @@ type fileTorrentImpl struct {
2626
client *fileClientImpl
2727
}
2828

29-
func (fts *fileTorrentImpl) logger() *slog.Logger {
30-
return fts.client.opts.Logger
29+
func (me *fileTorrentImpl) logger() *slog.Logger {
30+
return me.client.opts.Logger
3131
}
3232

33-
func (fts *fileTorrentImpl) pieceCompletion() PieceCompletion {
34-
return fts.client.opts.PieceCompletion
33+
func (me *fileTorrentImpl) pieceCompletion() PieceCompletion {
34+
return me.client.opts.PieceCompletion
3535
}
3636

37-
func (fts *fileTorrentImpl) pieceCompletionKey(p int) metainfo.PieceKey {
37+
func (me *fileTorrentImpl) pieceCompletionKey(p int) metainfo.PieceKey {
3838
return metainfo.PieceKey{
39-
InfoHash: fts.infoHash,
39+
InfoHash: me.infoHash,
4040
Index: p,
4141
}
4242
}
4343

44-
func (fts *fileTorrentImpl) setPieceCompletion(p int, complete bool) error {
45-
return fts.pieceCompletion().Set(fts.pieceCompletionKey(p), complete)
44+
func (me *fileTorrentImpl) setPieceCompletion(p int, complete bool) error {
45+
return me.pieceCompletion().Set(me.pieceCompletionKey(p), complete)
4646
}
4747

4848
// Set piece completions based on whether all files in each piece are not .part files.
49-
func (fts *fileTorrentImpl) setCompletionFromPartFiles() error {
50-
notComplete := make([]bool, fts.info.NumPieces())
51-
for fileIndex := range fts.files {
52-
f := fts.file(fileIndex)
49+
func (me *fileTorrentImpl) setCompletionFromPartFiles() error {
50+
notComplete := make([]bool, me.info.NumPieces())
51+
for fileIndex := range me.files {
52+
f := me.file(fileIndex)
5353
fi, err := os.Stat(f.safeOsPath)
5454
if err == nil {
5555
if fi.Size() == f.length() {
5656
continue
5757
}
58-
fts.logger().Warn("file has unexpected size", "file", f.safeOsPath, "size", fi.Size(), "expected", f.length())
58+
me.logger().Warn("file has unexpected size", "file", f.safeOsPath, "size", fi.Size(), "expected", f.length())
5959
} else if !errors.Is(err, fs.ErrNotExist) {
60-
fts.logger().Warn("error checking file size", "err", err)
60+
me.logger().Warn("error checking file size", "err", err)
6161
}
6262
// Ensure all pieces associated with a file are not marked as complete (at most unknown).
6363
for pieceIndex := f.beginPieceIndex(); pieceIndex < f.endPieceIndex(); pieceIndex++ {
@@ -66,14 +66,14 @@ func (fts *fileTorrentImpl) setCompletionFromPartFiles() error {
6666
}
6767
for i, nc := range notComplete {
6868
if nc {
69-
c := fts.getCompletion(i)
69+
c := me.getCompletion(i)
7070
if c.Complete {
7171
// TODO: We need to set unknown so that verification of the data we do have could
7272
// occur naturally but that'll be a big change.
73-
panicif.Err(fts.setPieceCompletion(i, false))
73+
panicif.Err(me.setPieceCompletion(i, false))
7474
}
7575
} else {
76-
err := fts.setPieceCompletion(i, true)
76+
err := me.setPieceCompletion(i, true)
7777
if err != nil {
7878
return fmt.Errorf("setting piece %v completion: %w", i, err)
7979
}
@@ -82,44 +82,44 @@ func (fts *fileTorrentImpl) setCompletionFromPartFiles() error {
8282
return nil
8383
}
8484

85-
func (fts *fileTorrentImpl) partFiles() bool {
86-
return fts.client.opts.partFiles()
85+
func (me *fileTorrentImpl) partFiles() bool {
86+
return me.client.opts.partFiles()
8787
}
8888

89-
func (fts *fileTorrentImpl) pathForWrite(f *file) string {
90-
if fts.partFiles() {
89+
func (me *fileTorrentImpl) pathForWrite(f *file) string {
90+
if me.partFiles() {
9191
return f.partFilePath()
9292
}
9393
return f.safeOsPath
9494
}
9595

96-
func (fts *fileTorrentImpl) getCompletion(piece int) Completion {
97-
cmpl, err := fts.pieceCompletion().Get(metainfo.PieceKey{fts.infoHash, piece})
96+
func (me *fileTorrentImpl) getCompletion(piece int) Completion {
97+
cmpl, err := me.pieceCompletion().Get(metainfo.PieceKey{me.infoHash, piece})
9898
cmpl.Err = errors.Join(cmpl.Err, err)
9999
return cmpl
100100
}
101101

102-
func (fts *fileTorrentImpl) Piece(p metainfo.Piece) PieceImpl {
102+
func (me *fileTorrentImpl) Piece(p metainfo.Piece) PieceImpl {
103103
// Create a view onto the file-based torrent storage.
104-
_io := fileTorrentImplIO{fts}
104+
_io := fileTorrentImplIO{me}
105105
// Return the appropriate segments of this.
106106
return &filePieceImpl{
107-
fts,
107+
me,
108108
p,
109109
missinggo.NewSectionWriter(_io, p.Offset(), p.Length()),
110110
io.NewSectionReader(_io, p.Offset(), p.Length()),
111111
}
112112
}
113113

114-
func (fs *fileTorrentImpl) Close() error {
115-
return nil
114+
func (me *fileTorrentImpl) Close() error {
115+
return me.io.Close()
116116
}
117117

118-
func (fts *fileTorrentImpl) file(index int) file {
118+
func (me *fileTorrentImpl) file(index int) file {
119119
return file{
120-
Info: fts.info,
121-
FileInfo: &fts.metainfoFileInfos[index],
122-
fileExtra: &fts.files[index],
120+
Info: me.info,
121+
FileInfo: &me.metainfoFileInfos[index],
122+
fileExtra: &me.files[index],
123123
}
124124
}
125125

@@ -153,8 +153,8 @@ func (me *fileTorrentImpl) openFile(file file) (f fileReader, err error) {
153153
return
154154
}
155155

156-
func (fst *fileTorrentImpl) openForWrite(file file) (_ fileWriter, err error) {
156+
func (me *fileTorrentImpl) openForWrite(file file) (_ fileWriter, err error) {
157157
// It might be possible to have a writable handle shared files cache if we need it.
158-
fst.logger().Debug("openForWrite", "file.safeOsPath", file.safeOsPath)
159-
return fst.io.openForWrite(fst.pathForWrite(&file), file.FileInfo.Length)
158+
me.logger().Debug("openForWrite", "file.safeOsPath", file.safeOsPath)
159+
return me.io.openForWrite(me.pathForWrite(&file), file.FileInfo.Length)
160160
}

0 commit comments

Comments
 (0)