Repository navigation
feat: Replace the expiringdict dependency with an internal cache - #563
Merged
Merged
Conversation
jsonbailey
marked this pull request as ready for review
November 4, 2026 23:31
keelerm84
approved these changes
Nov 5, 2026
keelerm84
left a comment
Member
There was a problem hiding this comment.
On the open question: I'd ship this in a minor release. An application that imports expiringdict without declaring it depends on our internals, and a changelog note covers that case.
jsonbailey
pushed a commit
that referenced
this pull request
Nov 5, 2026
🤖 I have created a release *beep* *boop* --- ## [9.20.0](9.19.0...9.20.0) (2026-11-05) ### Features * Replace the expiringdict dependency with an internal cache ([#563](#563)) ([ca34aad](ca34aad)) ### Bug Fixes * Ignore FDv2 objects with unrecognized kinds ([#541](#541)) ([d5eeb80](d5eeb80)) --- 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 PR that **bumps the SDK from 9.19.0 to 9.20.0** across `pyproject.toml`, `ldclient/version.py`, `.release-please-manifest.json`, and `PROVENANCE.md`, and adds the **9.20.0** section to `CHANGELOG.md`. > > That release (already merged on main) ships **replacement of the `expiringdict` dependency with an internal `ExpiringCache`**, and a fix to **skip FDv2 objects with unrecognized kinds** instead of failing on them. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit af7a7b3. 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
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.
Summary
Remove the
expiringdictdependency. The SDK now uses a small private class,ldclient.impl.expiring_cache.ExpiringCache. The persistent-store cache and the Big Segment membership caches (sync and async) use it.expiringdicthas had no release since 2022, and the SDK uses only a few of its features. The new class keeps this behavior:Two small differences:
time.monotonic(), nottime.time(), so wall-clock changes no longer affect it.expiringdict1.2.2, a rewrite keeps the key's original position unless the cache is full.Both projects are Apache 2.0. The class is new code, not a copy.
This ships in the current major version. An application that imports
expiringdictwithout declaring it as its own dependency must now add it.Note
Overview
Removes the
expiringdictdependency and wires caching through a new in-treeExpiringCache(ldclient.impl.expiring_cache).Persistent feature-store caching (
CachingStoreWrapper) and Big Segment membership caches (sync and async managers) now instantiateExpiringCachewith the same capacity and TTL settings as before. The new type is thread-safe and exposes the dict-like surface those call sites already use (get,__setitem__,pop,clear,__len__).Semantics are intentionally aligned with the old library: TTL is measured from last write, reads do not refresh expiry, and overflow evicts the first-written entry (FIFO, not LRU). One deliberate difference: expiry uses
time.monotonic()instead of wall clock time, so NTP or manual clock changes no longer shorten or extend cache lifetimes.Packaging:
expiringdictis dropped from main and docs optional dependencies. A large dedicated test suite covers TTL, eviction, and concurrency; an existing cache-lifecycle test comment is updated to refer to “the old cache” generically.Reviewed by Cursor Bugbot for commit b60b3fd. Bugbot is set up for automated code reviews on this repo. Configure here.