2
2
mirror of https://github.com/octoleo/restic.git synced 2024-05-30 15:40:50 +00:00
restic/internal/restic/readerat.go
Michael Eischer e638b46a13 Embed context into ReaderAt
The io.Reader interface does not support contexts, such that it is
necessary to embed the context into the backendReaderAt struct. This has
the problem that a reader might suddenly stop working when it's
contained context is canceled. However, this is now problem here as the
reader instances never escape the calling function.
2020-10-09 22:39:07 +02:00

45 lines
1.1 KiB
Go

package restic
import (
"context"
"io"
"github.com/restic/restic/internal/debug"
"github.com/restic/restic/internal/errors"
)
type backendReaderAt struct {
ctx context.Context
be Backend
h Handle
}
func (brd backendReaderAt) ReadAt(p []byte, offset int64) (n int, err error) {
return ReadAt(brd.ctx, brd.be, brd.h, offset, p)
}
// ReaderAt returns an io.ReaderAt for a file in the backend. The returned reader
// should not escape the caller function to avoid unexpected interactions with the
// embedded context
func ReaderAt(ctx context.Context, be Backend, h Handle) io.ReaderAt {
return backendReaderAt{ctx: ctx, be: be, h: h}
}
// ReadAt reads from the backend handle h at the given position.
func ReadAt(ctx context.Context, be Backend, h Handle, offset int64, p []byte) (n int, err error) {
debug.Log("ReadAt(%v) at %v, len %v", h, offset, len(p))
err = be.Load(ctx, h, len(p), offset, func(rd io.Reader) (ierr error) {
n, ierr = io.ReadFull(rd, p)
return ierr
})
if err != nil {
return 0, err
}
debug.Log("ReadAt(%v) ReadFull returned %v bytes", h, n)
return n, errors.Wrapf(err, "ReadFull(%v)", h)
}