Skip to content

Commit 6000d33

Browse files
committed
azure: use ResumingReader
Previously, the azure client did not use the ResumingReader. This was causing tracing span use after free issues as the client would issue http retries with a span that was already finished. The ResumingReader manages a span for the lifetime of the reader. There is also some evidence in #154483 that the RetryReader built into the azure client did not properly retry errors that occur while reading the body. Fixes: 154849 Release note: none
1 parent a56c46b commit 6000d33

File tree

1 file changed

+33
-17
lines changed

1 file changed

+33
-17
lines changed

pkg/cloud/azure/azure_storage.go

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -356,31 +356,47 @@ func isNotFoundErr(err error) bool {
356356
func (s *azureStorage) ReadFile(
357357
ctx context.Context, basename string, opts cloud.ReadOptions,
358358
) (_ ioctx.ReadCloserCtx, fileSize int64, _ error) {
359+
object := path.Join(s.prefix, basename)
360+
359361
ctx, sp := tracing.ChildSpan(ctx, "azure.ReadFile")
360362
defer sp.Finish()
361-
sp.SetTag("path", attribute.StringValue(path.Join(s.prefix, basename)))
362-
resp, err := s.getBlob(basename).DownloadStream(ctx, &azblob.DownloadStreamOptions{Range: azblob.
363-
HTTPRange{Offset: opts.Offset}})
364-
if err != nil {
365-
if isNotFoundErr(err) {
366-
return nil, 0, cloud.WrapErrFileDoesNotExist(err, "azure blob does not exist")
367-
}
368-
return nil, 0, errors.Wrapf(err, "failed to create azure reader")
369-
}
363+
sp.SetTag("path", attribute.StringValue(object))
370364

371-
if !opts.NoFileSize {
372-
if opts.Offset == 0 {
373-
fileSize = *resp.ContentLength
374-
} else {
375-
fileSize, err = cloud.CheckHTTPContentRangeHeader(*resp.ContentRange, opts.Offset)
365+
r := cloud.NewResumingReader(ctx,
366+
func(ctx context.Context, pos int64) (io.ReadCloser, int64, error) {
367+
resp, err := s.getBlob(basename).DownloadStream(ctx, &azblob.DownloadStreamOptions{
368+
Range: azblob.HTTPRange{Offset: pos},
369+
})
376370
if err != nil {
377371
return nil, 0, err
378372
}
373+
374+
length := *resp.ContentLength
375+
if 0 < pos {
376+
length, err = cloud.CheckHTTPContentRangeHeader(*resp.ContentRange, pos)
377+
if err != nil {
378+
return nil, 0, err
379+
}
380+
}
381+
382+
return resp.Body, length, nil
383+
},
384+
nil, // reader
385+
opts.Offset,
386+
0,
387+
object,
388+
cloud.ResumingReaderRetryOnErrFnForSettings(ctx, s.settings),
389+
nil, // errFn
390+
)
391+
392+
if err := r.Open(ctx); err != nil {
393+
if isNotFoundErr(err) {
394+
return nil, 0, cloud.WrapErrFileDoesNotExist(err, "azure blob does not exist")
379395
}
396+
return nil, 0, err
380397
}
381-
// BUG: we should follow the azure retry setting here.
382-
reader := resp.NewRetryReader(ctx, &azblob.RetryReaderOptions{MaxRetries: 3})
383-
return ioctx.ReadCloserAdapter(reader), fileSize, nil
398+
399+
return r, r.Size, nil
384400
}
385401

386402
func (s *azureStorage) List(ctx context.Context, prefix, delim string, fn cloud.ListingFn) error {

0 commit comments

Comments
 (0)