azure-sdk-for-js: Intermittent timeout errors from @azure/storage-blob

  • Package Name: @azure/storage-blob
  • Package Version: 12.0.0
  • Operating system: Windows Azure App Service
  • nodejs version 10.14.1

Describe the bug I am looking for any help troubleshooting a frequent error I am getting using this SDK. The error details are as below, and it happens intermittently

request to https://{accountName}.blob.core.windows.net/path failed, reason: connect ETIMEDOUT 13.70.99.30:443


at ClientRequest [anonymous] (D:\home\site\wwwroot\node_modules\@azure\core-http\node_modules\node-fetch\lib\index.js:1455)
at ClientRequest ClientRequest.clsBind (D:\home\site\wwwroot\node_modules\cls-hooked\context.js:172)
at ClientRequest ClientRequest.emit (events.js:187)
at ClientRequest ClientRequest.emitted (D:\home\site\wwwroot\node_modules\emitter-listener\listener.js:134)
at TLSSocket TLSSocket.socketErrorListener (_http_client.js:391)
at TLSSocket TLSSocket.emit (events.js:182)
at Object emitErrorNT (internal/streams/destroy.js:82)
at Object emitErrorAndCloseNT (internal/streams/destroy.js:50)
at process process._tickCallback (internal/process/next_tick.js:63)

To Reproduce Steps to reproduce the behavior: I do not have reliable reproduction steps

Expected behavior A clear and concise description of what you expected to happen. The SDK should not encounter timeouts when writing to the blob storage account

Additional context I understand there is not reliable reproduction steps, but any guidance to help me with this bug, or debug it would be really appreciated

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (11 by maintainers)

Most upvoted comments

Just to round this out for people viewing this issue in the future, the timeout problem we were experiencing was a problem with a server in a data center , which we have resolved by migrating.

Thanks for the work to optimise the client caching, and for all the attention this issue received. The support we have received has assured me that this library was a good choice for us.

I believe the cause is that For each of our clients (BlobServiceClient, ContainerClient, BlobClient, BlockBlobClient, etc.) there’s an underlying ServiceClient instance that handles sending request and receiving response from the Azure service. We have cached Http connection at ServiceClient level. However, in our current design two storage clients will not share a same connection (even if they have the same url to the corresponding Azure service resource. They do share the options from parent clients. So what’s happening in this repro code is that 500 block blob clients and 500 connection are created with keepAlive enabled.

@OP-Klaus does your real scenario use blob clients with different locations? If that’s the case you probably don’t want to enable keepAlive because http connections are not share among them and those connection would hang around for much longer time. If you use a same blob client many times it then makes sense to enable keepAlive and also cache the blob client instance based on its location.

BTW you can directly get a block blob client from container client.

Here’s my attempt to cache the block blob client

let _blobClients = {};
const getAzureBlobClient = (containerClient, location) => {
  let client = _blobClients[location];
  if (!client) {
    client = _blobClients[location] = containerClient.getBlockBlobClient(location);
  }

  return client;
}

const setPageContentToAzure = (location, content) => {
  const containerClient = getAzureContainerClient();
  const blockBlobClient = getAzureBlobClient(containerClient, location);

  return blockBlobClient.upload(content, content.length);
};

Also it might be useful for the SDK to maintain some cache of clients when getXxxxClient() is called. /cc @bterlson

#6657 addressed this issue by sharing a http client by default for all clients. It will be available in next release of blob storage packages.

@OP-Klaus thanks for sharing your insights to this problem. The network issue might become complex when it fall into PaaS case, as it’s transparent to user how underlay distributes and manages the network resources. Your work around sounds feasible, and feel free to let us know if you need further assist from us.