Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection timeout doesn't work. Documentation is unclear in regards to how to use that. #39580

Open
IvanovCosmin opened this issue Feb 5, 2025 · 3 comments
Assignees
Labels
Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Service Attention Workflow: This issue is responsible by Azure service team. Storage Storage Service (Queues, Blobs, Files)

Comments

@IvanovCosmin
Copy link

IvanovCosmin commented Feb 5, 2025

  • Package Name: azure-storage-queue
  • Package Version: 12.12.0
  • Operating System: Ubuntu
  • Python Version: 3.12

Describe the bug
I believe that there is no way to actually specify a connection timeout. All requests that happen when there is an internet hiccup just get stuck for a default of many seconds. I could not find any parameter to make it actually cancel the request.. We tried using custom sessions, custom transports, different timeout parameters, both sync and async.
I tried following the docs but it is not very clear https://learn.microsoft.com/en-us/python/api/overview/azure/storage-queue-readme?view=azure-python

To Reproduce

  1. Use a connection string that points to a localhost port. Can use azurite and just close the container.
  2. Use any of the following functions
import asyncio
from time import perf_counter
from aiohttp import ClientSession, ClientTimeout
from azure.storage.queue import QueueClient, QueueServiceClient
import azure.storage.queue.aio as queue_aio

from starlette.config import Config

# https://learn.microsoft.com/en-us/python/api/overview/azure/storage-queue-readme?view=azure-python

config = Config(".env")

CONN_STRING = config("AZURE_STORAGE_QUEUE_CONNECTION_STRING")


async def main_directly_queue_client():
    queue_client = QueueClient.from_connection_string(
        CONN_STRING,
        "myqueue",
        timeout=1,
        read_timeout=1,
        connection_timeout=1,  # connection_timeout is ignored
    )
    now = perf_counter()

    conn_config = queue_client._pipeline._transport.connection_config
    print(
        f"connection_config {conn_config.timeout=}, {conn_config.read_timeout=}"
    )  # connection_config conn_config.timeout=1, conn_config.read_timeout=1
    try:
        queue_client.create_queue(
            timeout=1, connection_timeout=1
        )  # connection_timeout is ignored
    except Exception as e:
        pass
    finally:
        print(f"Time taken: {perf_counter() - now:.2f} seconds") 


async def main_use_queue_service_client():
    queue_service_client = QueueServiceClient.from_connection_string(
        CONN_STRING,
        timeout=1,
        connection_timeout=1,
        read_timeout=1,
    )
    queue_client = queue_service_client.get_queue_client("myqueue")

    now = perf_counter()

    conn_config = queue_client._pipeline._transport._transport.connection_config
    print(
        f"connection_config {conn_config.timeout=}, {conn_config.read_timeout=}"
    )  # connection_config conn_config.timeout=1, conn_config.read_timeout=1
    try:
        queue_client.create_queue(
            timeout=1, connection_timeout=1
        )  # connection_timeout is ignored
    except Exception as e:
        pass
    finally:
        print(f"Time taken: {perf_counter() - now:.2f} seconds") 

async def main_use_asyncio():
    queue_service_client = queue_aio.QueueServiceClient.from_connection_string(
        CONN_STRING,
        timeout=1,
        connection_timeout=1,
        read_timeout=1,
    )
    queue_client = queue_service_client.get_queue_client("myqueue")
    conn_config = queue_client._pipeline._transport._transport.connection_config
    print(
        f"connection_config {conn_config.timeout=}, {conn_config.read_timeout=}"
    )  # connection_config conn_config.timeout=1, conn_config.read_timeout=1
    now = perf_counter()
    try:
        await queue_client.create_queue(
            timeout=1, connection_timeout=1
        )  # connection_timeout is ignored
    except Exception as e:
        pass
    finally:
        print(f"Time taken: {perf_counter() - now:.2f} seconds") 

class ProxyClientSession(ClientSession):

    def _request(self, *args, **kwargs):
        print(f"{args}")
        print(f"{kwargs}")
        return super()._request(*args, **kwargs)


async def main_use_asyncio_but_closer():
    from azure.core.pipeline.transport import AioHttpTransport

    transport = AioHttpTransport(
        session=ProxyClientSession(
            timeout=ClientTimeout(total=2, connect=2, sock_connect=2, sock_read=2)
        )
    )
    queue_service_client = queue_aio.QueueServiceClient.from_connection_string(
        CONN_STRING,
        transport=transport,
        timeout=1,
        connection_timeout=1,
        read_timeout=1,
    )
    queue_client = queue_service_client.get_queue_client("myqueue")
    conn_config = queue_client._pipeline._transport._transport.connection_config
    print(
        f"connection_config {conn_config.timeout=}, {conn_config.read_timeout=}"
    )  # connection_config conn_config.timeout=300, conn_config.read_timeout=300
    now = perf_counter()
    try:
        await queue_client.create_queue(
            timeout=1, connection_timeout=1
        )  # connection_timeout is ignored
    except Exception as e:
        pass
    finally:
        print(f"Time taken: {perf_counter() - now:.2f} seconds") # Time taken: 90.94 seconds


asyncio.run(main_use_asyncio_but_closer())

Expected behavior
I want to be able to set a connection timeout. We mostly care about the async path.

@github-actions github-actions bot added customer-reported Issues that are reported by GitHub users external to the Azure organization. needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Feb 5, 2025
@xiangyan99 xiangyan99 added Storage Storage Service (Queues, Blobs, Files) Service Attention Workflow: This issue is responsible by Azure service team. Client This issue points to a problem in the data-plane of the library. and removed needs-triage Workflow: This is a new issue that needs to be triaged to the appropriate team. labels Feb 5, 2025
@github-actions github-actions bot added the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Feb 5, 2025
Copy link

github-actions bot commented Feb 5, 2025

Thanks for the feedback! We are routing this to the appropriate team for follow-up. cc @jalauzon-msft @vincenttran-msft.

@jalauzon-msft
Copy link
Member

Hi @IvanovCosmin, thanks for reaching out. I believe you are likely seeing this behavior because of the automatic retry of the SDK. The default retry policy has some very long retry times (its exponential with an initial backoff of 15 seconds and default of 3 tries) which can result in the 60+ seconds of waiting you are seeing. we Realize these default values are not the best and have been discussing changing them but for now, you can configure the retry policy yourself to either eliminate or reduce the time of the automatic retries. See Implement a retry policy with Python for details on how to do that and all the values that can be adjusted. The easiest approach may be to set initial_backoff and increment_base to much smaller values on client construction but things can be configured in many ways.

In terms of the timeout, connection_timeout and read_timeout are the values you will want to be setting to configure the client-side networking timeouts. These should be working properly once you configure your retry. The timeout keyword you see on all operations configures the server-side timeout and is probably not helpful in this situation.

Hopefully this helps, thanks.

@jalauzon-msft jalauzon-msft added the issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. label Feb 13, 2025
@github-actions github-actions bot removed the needs-team-attention Workflow: This issue needs attention from Azure service team or SDK team label Feb 13, 2025
Copy link

Hi @IvanovCosmin. Thank you for opening this issue and giving us the opportunity to assist. We believe that this has been addressed. If you feel that further discussion is needed, please add a comment with the text "/unresolve" to remove the "issue-addressed" label and continue the conversation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Client This issue points to a problem in the data-plane of the library. customer-reported Issues that are reported by GitHub users external to the Azure organization. issue-addressed Workflow: The Azure SDK team believes it to be addressed and ready to close. question The issue doesn't require a change to the product in order to be resolved. Most issues start as that Service Attention Workflow: This issue is responsible by Azure service team. Storage Storage Service (Queues, Blobs, Files)
Projects
None yet
Development

No branches or pull requests

4 participants