Skip to content

fix: Reuse an in-flight big segment status poll instead of always querying twice - #535

Merged
jsonbailey merged 1 commit into
mainfrom
jb/fix/bigsegments-double-startup-poll
Oct 6, 2026
Merged

jsonbailey merged 1 commit into
mainfrom
jb/fix/bigsegments-double-startup-poll

Conversation

@jsonbailey

@jsonbailey jsonbailey commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

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_membership now goes through get_status instead 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_metadata and a long poll interval, a startup status request must produce exactly one metadata query. Both fail assert 2 == 1 without the fix.

  • pytest ldclient/testing (excluding integrations): 1667 passed
  • make lint: clean, 229 source files
  • Contract tests, zero failures: v3 sync 4756 ran, v3 async 4753 ran, v2 sync 4741 ran, v2 async 4738 ran

Tracked 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 separate get_metadata query.

Sync and async BigSegmentStoreManager now 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_membership routes status through get_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.

@jsonbailey
jsonbailey marked this pull request as ready for review October 5, 2026 14:15
@jsonbailey
jsonbailey requested a review from a team as a code owner October 5, 2026 14:15
@jsonbailey
jsonbailey marked this pull request as draft October 5, 2026 15:05
…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.
@jsonbailey
jsonbailey force-pushed the jb/fix/bigsegments-double-startup-poll branch from da5aaa5 to 4eadad3 Compare October 5, 2026 22:27
@jsonbailey jsonbailey changed the title fix: Delay the first big segment status poll by one interval fix: Reuse an in-flight big segment status poll instead of querying twice Oct 5, 2026
@jsonbailey
jsonbailey marked this pull request as ready for review October 5, 2026 22:29

@joker23 joker23 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

@jsonbailey

Copy link
Copy Markdown
Contributor Author

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.

@jsonbailey jsonbailey changed the title fix: Reuse an in-flight big segment status poll instead of querying twice fix: Reuse an in-flight big segment status poll instead of always querying twice Oct 6, 2026
@jsonbailey
jsonbailey merged commit 66013b5 into main Oct 6, 2026
20 checks passed
@jsonbailey
jsonbailey deleted the jb/fix/bigsegments-double-startup-poll branch October 6, 2026 22:05
jsonbailey pushed a commit that referenced this pull request Oct 6, 2026
🤖 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>
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.

3 participants