Skip to content

Commit 0e81002

Browse files
authored
fix(storage/transfermanager): WaitAndClose waits for Callbacks to finish (#10504)
Fixes #10502
1 parent 727b6c8 commit 0e81002

File tree

1 file changed

+19
-16
lines changed

1 file changed

+19
-16
lines changed

storage/transfermanager/downloader.go

+19-16
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ func (d *Downloader) DownloadDirectory(ctx context.Context, input *DownloadDirec
139139
}
140140

141141
if d.config.asynchronous {
142-
go input.gatherObjectOutputs(outs, len(inputs))
142+
d.downloadsInProgress.Add(1)
143+
go d.gatherObjectOutputs(input, outs, len(inputs))
143144
}
144145
d.addNewInputs(inputs)
145146
return nil
@@ -359,6 +360,22 @@ func (d *Downloader) gatherShards(in *DownloadObjectInput, outs <-chan *Download
359360
d.addResult(in, shardOut)
360361
}
361362

363+
// gatherObjectOutputs receives from the given channel exactly numObjects times.
364+
// It will execute the callback once all object outputs are received.
365+
// It does not do any verification on the outputs nor does it cancel other
366+
// objects on error.
367+
func (d *Downloader) gatherObjectOutputs(in *DownloadDirectoryInput, gatherOuts <-chan DownloadOutput, numObjects int) {
368+
outs := make([]DownloadOutput, 0, numObjects)
369+
for i := 0; i < numObjects; i++ {
370+
obj := <-gatherOuts
371+
outs = append(outs, obj)
372+
}
373+
374+
// All objects have been gathered; execute the callback.
375+
in.Callback(outs)
376+
d.downloadsInProgress.Done()
377+
}
378+
362379
func (d *Downloader) validateObjectInput(in *DownloadObjectInput) error {
363380
if d.config.asynchronous && in.Callback == nil {
364381
return errors.New("transfermanager: input.Callback must not be nil when the WithCallbacks option is set")
@@ -567,27 +584,13 @@ type DownloadDirectoryInput struct {
567584
// Callback will run after all the objects in the directory as selected by
568585
// the provided filters are finished downloading.
569586
// It must be set if and only if the [WithCallbacks] option is set.
587+
// WaitAndClose will wait for all callbacks to finish.
570588
Callback func([]DownloadOutput)
571589

572590
// OnObjectDownload will run after every finished object download. Optional.
573591
OnObjectDownload func(*DownloadOutput)
574592
}
575593

576-
// gatherObjectOutputs receives from the given channel exactly numObjects times.
577-
// It will call the callback once all object outputs are received.
578-
// It does not do any verification on the outputs nor does it cancel other
579-
// objects on error.
580-
func (dirin *DownloadDirectoryInput) gatherObjectOutputs(gatherOuts <-chan DownloadOutput, numObjects int) {
581-
outs := make([]DownloadOutput, 0, numObjects)
582-
for i := 0; i < numObjects; i++ {
583-
obj := <-gatherOuts
584-
outs = append(outs, obj)
585-
}
586-
587-
// All objects have been gathered; execute the callback.
588-
dirin.Callback(outs)
589-
}
590-
591594
// DownloadOutput provides output for a single object download, including all
592595
// errors received while downloading object parts. If the download was successful,
593596
// Attrs will be populated.

0 commit comments

Comments
 (0)