@@ -242,6 +242,7 @@ type ReaderOpenerAt func(ctx context.Context, pos int64) (io.ReadCloser, int64,
242
242
type ResumingReader struct {
243
243
Opener ReaderOpenerAt // Get additional content
244
244
Reader io.ReadCloser // Currently opened reader
245
+ ReaderSpan * tracing.Span // Span for the current reader, if Reader is non-nil
245
246
Filename string // Used for logging
246
247
Pos int64 // How much data was received so far
247
248
Size int64 // Total size of the file
@@ -284,6 +285,10 @@ func NewResumingReader(
284
285
285
286
// Open opens the reader at its current offset.
286
287
func (r * ResumingReader ) Open (ctx context.Context ) error {
288
+ if r .Reader != nil {
289
+ return errors .AssertionFailedf ("reader already open" )
290
+ }
291
+
287
292
if r .Size > 0 && r .Pos >= r .Size {
288
293
// Don't try to open a file if the size has been set and the position is
289
294
// at size. This generally results in an invalid range error for the
@@ -294,10 +299,18 @@ func (r *ResumingReader) Open(ctx context.Context) error {
294
299
295
300
return DelayedRetry (ctx , "Open" , r .ErrFn , func () error {
296
301
var readErr error
302
+
303
+ ctx , span := tracing .ForkSpan (ctx , "resuming-reader" )
297
304
r .Reader , r .Size , readErr = r .Opener (ctx , r .Pos )
298
305
if readErr != nil {
306
+ span .Finish ()
299
307
return errors .Wrapf (readErr , "open %s" , r .Filename )
300
308
}
309
+
310
+ // We hold onto the span for the lifetime of the reader because the reader
311
+ // may issue new HTTP requests after Open returns.
312
+ r .ReaderSpan = span
313
+
301
314
return nil
302
315
})
303
316
}
@@ -340,10 +353,9 @@ func (r *ResumingReader) Read(ctx context.Context, p []byte) (int, error) {
340
353
}
341
354
log .Dev .Errorf (ctx , "Retry IO error: %s" , lastErr )
342
355
lastErr = nil
343
- if r .Reader != nil {
344
- r .Reader .Close ()
345
- }
346
- r .Reader = nil
356
+ // Ignore the error from Close(). We are already handling a read error
357
+ // so we know the handle is in a bad state.
358
+ _ = r .Close (ctx )
347
359
}
348
360
}
349
361
@@ -356,10 +368,14 @@ func (r *ResumingReader) Read(ctx context.Context, p []byte) (int, error) {
356
368
357
369
// Close implements io.Closer.
358
370
func (r * ResumingReader ) Close (ctx context.Context ) error {
359
- if r .Reader ! = nil {
360
- return r . Reader . Close ()
371
+ if r .Reader = = nil {
372
+ return nil
361
373
}
362
- return nil
374
+
375
+ err := r .Reader .Close ()
376
+ r .ReaderSpan .Finish ()
377
+ r .Reader = nil
378
+ return err
363
379
}
364
380
365
381
// CheckHTTPContentRangeHeader parses Content-Range header and ensures that
0 commit comments