chore: Add async support classes for concurrency and HTTP transport#451
Merged
Conversation
…ridges Aligns the slice with the impl branch: impl/shims/ -> impl/aio/ (concurrency.py, transport.py, transport_types.py), test -> testing/test_aio.py. The package is a genuine async support library, not a compatibility shim.
keelerm84
approved these changes
Jul 15, 2026
Rewrite join_handle on asyncio.wait instead of wait_for+shield, which reported completion via done/pending sets rather than raising. Caller cancellation now propagates cleanly and is never conflated with the joined task's own cancellation. Adds a regression test.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 84dbd7b. Configure here.
keelerm84
approved these changes
Jul 16, 2026
Reuse ldclient.impl.http._get_proxy_url and disable aiohttp trust_env so the async transport applies the same proxy env-var casing and NO_PROXY rules as the sync SDK. Adds proxy-resolution parity tests.
Drop the _resolve_proxy helper; store the static config proxy on the transport/factory and fall back to the sync SDK's _get_proxy_url per request. Rewrite the proxy tests to assert the proxy passed through the real request path.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Adds the async support classes the async SDK is built on, under
ldclient/impl/aio/. Pure-additive: the package is dormant until its first consumer lands in a later slice, so it adds no runtime surface tomainbeyond the new (as-yet-unimported) modules.aio/concurrency.py— async concurrency primitives:AsyncEvent,AsyncLock,AsyncQueue,AsyncRepeatingTask,AsyncWorkerPool,AsyncTaskRunner,AsyncCallbackScheduler, andspawn_handle/join_handle. Each wraps a piece of fiddly asyncio plumbing (timeout-aware waits, queue exception normalization, an interval-from-start repeating task, a bounded task pool) that async callers would otherwise inline repeatedly.aio/transport.py— async HTTP/SSE transport (AsyncHTTPTransport,AsyncSSEFactory,make_client_session) over aiohttp.aio/transport_types.py— the sharedTransportResponse.testing/test_aio.py— unit tests for the above (they previously shipped untested).pyproject.toml— the async packaging these need: the[async]aiohttp extra plusaiohttp/pytest-asynciodev deps andasyncio_mode="strict"(the tests run under pytest-asyncio, so CI can't pass without it).Why
Foundation for the async Python SDK (epic SDK-60). These are genuine async support classes, not a compatibility shim: there is no sync twin — the sync code uses the equivalent stdlib/SDK primitives (
threading,queue.Queue,RepeatingTask,FixedThreadPool, urllib3) directly.Consumed by later slices:
concurrency.pyfirst by async big segments and the async flag tracker, then the event processor, data sources, and data systems;transport.pyfirst by async FDv1 streaming/polling, then the event processor and FDv2 sources.Validation
uv run pytest ldclient/testing/test_aio.py— 28 passeduv run mypy ldclient— cleanRefs SDK-2601 (epic SDK-60).
Note
Low Risk
Purely additive, unimported by the main SDK at merge; risk is limited to optional dependency and test/CI configuration, not production sync behavior.
Overview
Introduces
ldclient/impl/aio/as additive groundwork for the async Python SDK: concurrency helpers and aiohttp-based networking, plus tests and packaging so CI can run them. Nothing in the shipped client imports these modules yet.Concurrency (
concurrency.py) centralizes asyncio patterns that mirror existing sync primitives (RepeatingTask,FixedThreadPool, threading-style events/queues): timeout-friendlyAsyncEvent/AsyncQueue,AsyncRepeatingTask, boundedAsyncWorkerPool,AsyncTaskRunner, thread-safeAsyncCallbackScheduler, andspawn_handle/join_handlewith logged/cancelled background work.Transport (
transport.py,transport_types.py) addsTransportResponse,make_client_session(TLS/certs fromHTTPConfig),AsyncHTTPTransport, andAsyncSSEFactorywired told_eventsourcewith the same proxy rules as sync (_get_proxy_url,trust_env=False).Tests & deps:
ldclient/testing/test_aio.pycovers primitives and HTTP/proxy behavior;pyproject.tomladds optional[async]aiohttp extra, devaiohttp/pytest-asyncio, andasyncio_mode = "strict".Reviewed by Cursor Bugbot for commit 9347c9a. Bugbot is set up for automated code reviews on this repo. Configure here.