diff --git a/sdk/storage/azblob/CHANGELOG.md b/sdk/storage/azblob/CHANGELOG.md index 7270e1383744..24361be162e2 100644 --- a/sdk/storage/azblob/CHANGELOG.md +++ b/sdk/storage/azblob/CHANGELOG.md @@ -7,6 +7,7 @@ ### Breaking Changes ### Bugs Fixed +* Fix concurrency issue while Downloading File. Fixes [#22156](https://github.com/Azure/azure-sdk-for-go/issues/22156). ### Other Changes diff --git a/sdk/storage/azblob/blob/client.go b/sdk/storage/azblob/blob/client.go index 5b3cf5544550..8f651a835f22 100644 --- a/sdk/storage/azblob/blob/client.go +++ b/sdk/storage/azblob/blob/client.go @@ -9,6 +9,7 @@ package blob import ( "context" "io" + "math" "os" "sync" "time" @@ -469,23 +470,18 @@ func (b *Client) downloadFile(ctx context.Context, writer io.Writer, o downloadO buffers := shared.NewMMBPool(int(o.Concurrency), o.BlockSize) defer buffers.Free() - acquireBuffer := func() ([]byte, error) { - select { - case b := <-buffers.Acquire(): - // got a buffer - return b, nil - default: - // no buffer available; allocate a new buffer if possible - if _, err := buffers.Grow(); err != nil { - return nil, err - } - // either grab the newly allocated buffer or wait for one to become available - return <-buffers.Acquire(), nil + numChunks := uint16((count-1)/o.BlockSize + 1) + for bufferCounter := float64(0); bufferCounter < math.Min(float64(numChunks), float64(o.Concurrency)); bufferCounter++ { + if _, err := buffers.Grow(); err != nil { + return 0, err } } - numChunks := uint16((count-1)/o.BlockSize) + 1 + acquireBuffer := func() ([]byte, error) { + return <-buffers.Acquire(), nil + } + blocks := make([]chan []byte, numChunks) for b := range blocks { blocks[b] = make(chan []byte)