FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

feat: Add async DynamoDB persistent feature store by jsonbailey · Pull Request #490 · launchdarkly/python-server-sdk · GitHub

feat: Add async DynamoDB persistent feature store - #490

Merged
jsonbailey merged 4 commits into
mainfrom
jb/sdk-2906/async-persist-dynamodb
Aug 28, 2026
Merged

feat: Add async DynamoDB persistent feature store#490
jsonbailey merged 4 commits into
mainfrom
jb/sdk-2906/async-persist-dynamodb

Conversation

jsonbailey commented Aug 14, 2026
edited by cursor Bot
Loading

Copy link
Copy Markdown
Contributor

Overview

Adds an async DynamoDB persistent feature store: AsyncDynamoDBFeatureStore,
constructed via DynamoDB.async_feature_store(...). It builds directly on the async
persistence foundation merged in #488 (AsyncFeatureStoreCore + AsyncCachingStoreWrapper),
providing the DynamoDB-backed core.

The store uses the same table layout and key schema as the synchronous DynamoDB feature
store, so an async SDK and a synchronous SDK can share a single DynamoDB table.

New optional dependency

Adds an async-dynamodb extra that pulls in aioboto3. boto3 is sync-only, so async
access needs aioboto3 (which runs on aiobotocore). The existing sync dynamodb extra
(boto3) is unchanged.

Client lifecycle

aioboto3 clients are async context managers and cannot be created in __init__ the way
the sync boto3 client is. The client is therefore created lazily on first use, bound to the
running event loop, kept for the lifetime of the store, and released in close().

Testing

Unit tests that do not need a backend (the caching-wrapper wiring and the missing-aioboto3
guard) run in the normal suite. The integration tests require a live DynamoDB Local instance,
so they run in CI rather than locally.

Notes

  • SDK-2906
  • Draft pending review.

feat: Add async DynamoDB persistent feature store


Note

Overview
Adds DynamoDB.async_feature_store(...) for AsyncLDClient, wrapping a new _AsyncDynamoDBFeatureStoreCore with AsyncCachingStoreWrapper. The core mirrors the sync DynamoDB layout (JSON item, versioned upserts, non-atomic init with post-hoc deletes) but uses aioboto3 with lazy client creation under an asyncio.Lock, AsyncExitStack lifecycle, and close() that prevents new clients after shutdown.

Documents the feature as experimental, adds the async-dynamodb optional extra (aioboto3>=11.0), and includes integration tests against DynamoDB Local plus unit tests for wiring, missing aioboto3, and post-close client access.

Reviewed by Cursor Bugbot for commit 4dc3cb6. Bugbot is set up for automated code reviews on this repo. Configure here.

Builds on the async persistence foundation (AsyncFeatureStoreCore +
AsyncCachingStoreWrapper). Adds the async-dynamodb extra pulling aioboto3.
jsonbailey marked this pull request as ready for review August 28, 2026 13:35
jsonbailey requested a review from a team as a code owner August 28, 2026 13:35

cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

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 ed9fdbe. Configure here.

close() now takes _client_lock and sets a _closed flag before tearing
down the exit stack, so it cannot interleave with an in-flight lazy
client creation (which would register the new client on an already-closed
stack and leak it). _get_client() checks _closed under the lock and
raises rather than building a client after close.
return self._client
async with self._client_lock:
if self._closed:
raise RuntimeError("DynamoDB feature store is closed")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

I'm not a fan of raising an exception, but this shouldn't ever happen in practice right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

This should never happen and if it did, the exception would be treated as store unavailable upstream. I can switch it if needed, but it should be safe.

jsonbailey merged commit cb010df into main Aug 28, 2026
15 checks passed
jsonbailey deleted the jb/sdk-2906/async-persist-dynamodb branch August 28, 2026 20:25
jsonbailey pushed a commit that referenced this pull request Aug 28, 2026
🤖 I have created a release *beep* *boop*
---


##
[9.17.0](9.16.1...9.17.0)
(2026-08-28)


### Features

* Add async big segment store manager and async Redis adapter
([#462](#462))
([aa492d2](aa492d2))
* Add async DynamoDB persistent feature store
([#490](#490))
([cb010df](cb010df))
* Add async event processor
([ec7c113](ec7c113))
* Add async event processor
([#472](#472))
([ec7c113](ec7c113))
* Add async FDv1 polling data source and feature requester
([#475](#475))
([cca37a8](cca37a8))
* Add async FDv1 streaming and data source status tracking
([#464](#464))
([4bf7067](4bf7067))
* Add async FDv2 data sources
([#485](#485))
([5da1515](5da1515))
* Add async FDv2 data system
([#486](#486))
([6a70132](6a70132))
* Add async hook, plugin, and flag tracker
([#463](#463))
([686a70a](686a70a))
* Add async migration support
([#470](#470))
([577d51e](577d51e))
* Add async persistent feature store foundation and Redis adapter
([f9c76ee](f9c76ee))
* Add AsyncConfig for the async SDK client
([#471](#471))
([0587a78](0587a78))
* Add AsyncLDClient with FDv1 data system and public API
([#480](#480))
([fd041a5](fd041a5))
* Add Config.with_wrapper_information
([#501](#501))
([8a98583](8a98583))
* Add environment ID support for hooks.
([#484](#484))
([49e809f](49e809f))
* Add read-only store views and async persistence foundation for the
data system
([#503](#503))
([0eb61fa](0eb61fa))


### Bug Fixes

* Allow tombstones without a key property
([#502](#502))
([5f44e61](5f44e61))
* Escape attribute names reported in redactedAttributes
([#505](#505))
([90059cb](90059cb))
* Prevent a persistent-store outage from throwing in the sync FDv2
evaluation
([#506](#506))
([467da53](467da53))
* Return empty prerequisites for a flag that fails to evaluate in
all_flags_state
([#483](#483))
([73e9b07](73e9b07))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Overview**
> **Release Please** bumps the package from **9.16.1** to **9.17.0** in
`pyproject.toml`, `ldclient/version.py`,
`.release-please-manifest.json`, and the provenance example in
`PROVENANCE.md`.
> 
> `CHANGELOG.md` gains a new **9.17.0** (2026-08-28) section that
records what ships in this minor release: a broad **async** surface
(`AsyncLDClient`, `AsyncConfig`, async FDv1/FDv2 data systems, event
processor, hooks/plugins, migration, and Redis/DynamoDB persistent
stores plus big-segment async support), plus sync improvements
(`Config.with_wrapper_information`, hook environment ID, read-only store
views) and bug fixes (tombstones, `redactedAttributes` escaping, FDv2
persistent-store resilience, `all_flags_state` prerequisites).
> 
> No application logic changes appear in this diff—only version metadata
and release notes.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
f225e46. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants


Back | FazBrowse Home | New Git URL