Repository navigation
fix: Reuse an in-flight big segment status poll instead of always querying twice - #535
Conversation
…wice The status polling task queries the store as soon as it starts, and get_status also queries whenever no status is cached. A status request arriving while that first query was in flight found nothing cached and sent a second query, so startup could cost two metadata queries instead of one. A status request now waits for a poll that is already running rather than starting its own. The polling schedule is unchanged, so the first poll still happens immediately. get_user_membership now goes through get_status instead of repeating the cache check.
da5aaa5 to
4eadad3
Compare
joker23
left a comment
There was a problem hiding this comment.
nit: I think there is still a chance for double notification if (somehow) poll does not obtain the lock before get_status(), but this is still a big improvement.
Suggestion would be to change the pr title to:
fix: Reuse an in-flight big segment status poll instead of always querying twice
Poll and Update status will always update status unconditionally, that is its job. Get status will only update status if one is not currently set, and it needs to ensure that the status it returns is also set in the status provider. If poll then also updates, the notifier will dedupe and ensure it isn't broadcast twice unless it has changed status between the two. |
🤖 I have created a release *beep* *boop* --- ## [9.18.1](9.18.0...9.18.1) (2026-10-06) ### Bug Fixes * Reuse an in-flight big segment status poll instead of always querying twice ([#535](#535)) ([66013b5](66013b5)) --- 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** > This **Release Please** PR cuts **9.18.1** by bumping the package version everywhere it is declared (`.release-please-manifest.json`, `pyproject.toml`, `ldclient/version.py`, and the `SDK_VERSION` example in `PROVENANCE.md`). > > `CHANGELOG.md` documents the patch contents: a **bug fix** ([#535](#535)) that **reuses an in-flight big segment status poll** instead of issuing duplicate store queries when status is requested while a poll is already running. > > There are **no runtime code changes** in this diff—only release metadata and changelog text for the already-merged fix. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit becaab4. 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>
The status polling task queries the Big Segment store as soon as it starts, and
get_status()also queries whenever no status is cached yet. A status request arriving while that first query was still in flight found nothing cached and sent a second query, so startup could cost two metadata queries instead of one.A status request now waits for a poll that is already running rather than starting its own. The polling schedule is unchanged — the first poll still fires immediately, so nothing is delayed.
get_user_membershipnow goes throughget_statusinstead of repeating the cache check.Never slower than before, and faster when the caller arrives after the poll started: with a 250 ms store round trip, a status request at t=100 ms gets its answer at 255 ms instead of 358 ms.
Testing
New regression tests on both the sync and async managers: with a slow
get_metadataand a long poll interval, a startup status request must produce exactly one metadata query. Both failassert 2 == 1without the fix.pytest ldclient/testing(excluding integrations): 1667 passedmake lint: clean, 229 source filesTracked Internally: SDK-3212
Note
Overview
Fixes a startup race where the background Big Segment status poller and an uncached
get_status()call could each issue a separateget_metadataquery.Sync and async
BigSegmentStoreManagernow coordinate polls with a lock: only one metadata query runs at a time, and callers with no cached status wait on an in-flight poll instead of starting another. Store querying is split into__query_store_status()(under the lock); listener notification moves to__notify_status()outside the lock to avoid deadlocks if a listener re-enters the manager.get_user_membershiproutes status throughget_status()instead of duplicating the “poll if empty” path.Regression tests assert exactly one metadata query when a status read overlaps the first slow poll at startup.
Reviewed by Cursor Bugbot for commit 4eadad3. Bugbot is set up for automated code reviews on this repo. Configure here.