Skip to content

Document client assignment request reliability - #39560

Open
leoromanovsky wants to merge 2 commits into
masterfrom
leo.romanovsky/document-flag-assignment-reliability
Open

Document client assignment request reliability#39560
leoromanovsky wants to merge 2 commits into
masterfrom
leo.romanovsky/document-flag-assignment-reliability

Conversation

@leoromanovsky

@leoromanovsky leoromanovsky commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Motivation

Client applications need a visible way to protect assignment initialization from stalled requests without changing default SDK behavior. The primary setup path should show a bounded timeout, while the platform guides retain the complete timeout, retry, and lower-level transport building blocks.

This PR consolidates the cross-client documentation and supersedes #38869, #38870, #38871, #38872, and #38873.

Changes

  • Add an early getting-started warning and a timeout-only browser setup example capped at 1,500 milliseconds.
  • Add timeout-only setup examples for iOS, Android, Flutter, and Unity. Unity uses one second because its API accepts whole seconds.
  • Document browser flagConfigurationFetch with withRetry(withTimeout(globalThis.fetch, timeoutMs), retries) in advanced configuration.
  • Document opt-in scalar timeout/retry controls for iOS, Android, Flutter, and Unity in advanced configuration.
  • Add composable assignment-only examples for iOS AssignmentRequestFetch, Android Call.Factory, Dart http.Client, and Unity IAssignmentRequestTransport.
  • Clarify transport ownership, policy precedence, full-body timeout scope, fresh request attempts, and telemetry isolation.

Decisions

  • Preserve default request behavior across every client: 0 disables the SDK timeout and retry policies, producing one initial request while underlying platform/custom transport limits remain authoritative.
  • Show a timeout in primary setup guidance, keep retry configuration in advanced guidance, and keep every recommended timeout at or below 1,500 milliseconds.
  • Retry network errors, timeouts, HTTP 408, and HTTP 5xx only when explicitly configured; never retry HTTP 429.
  • Defer React Native documentation until the iOS and Android APIs are published and React Native can consume released native versions.
  • Keep this PR draft until every documented native API is released.

Validation

  • git diff --check passes.
  • Vale over all client/getting-started pages reports 0 errors.
  • Examples were checked against the exact public API fixtures and live draft PR heads.
  • A full Hugo build is unavailable in this sparse documentation worktree because build dependencies and Makefile.config are absent.

Dependencies

  1. Browser @datadog/openfeature-browser@1.4.0 is published to npm as latest.
  2. iOS [FFL-2891] Add composable assignment request transport dd-sdk-ios#3167 and Android [FFL-2929] Add composable assignment request transport dd-sdk-android#3693 can land independently.
  3. Flutter [FFL-2930] Add composable assignment request transport dd-sdk-flutter#1104 and Unity [FFL-2931] Add composable assignment request transport dd-sdk-unity#239 can land independently.
  4. React Native follows only after released iOS and Android versions are available.
  5. Merge this documentation PR after the documented SDK versions are released.

@leoromanovsky leoromanovsky changed the title Document client assignment request timeouts and retries Document client assignment request reliability Aug 28, 2026
Document zero-default assignment timeout and retry controls for supported client SDKs, including composable transport examples. Defer React Native until released native dependencies are available.

Environment: Datadog workspace
@leoromanovsky
leoromanovsky force-pushed the leo.romanovsky/document-flag-assignment-reliability branch from bb55615 to a1b96ad Compare August 28, 2026 23:20
@leoromanovsky
leoromanovsky marked this pull request as ready for review September 1, 2026 17:24
@leoromanovsky
leoromanovsky requested a review from a team as a code owner September 1, 2026 17:24
@leoromanovsky

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot 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.

🤖 Automated review by Claude. AI-generated; verify before acting.

Content is accurate and complete. Two blocker-adjacent findings on the new snippets/alert copy, plus one consistency nit.

Reviewed 030aba59578b1c918e736d9f81fb2957934d7f5bworkflow run

For lower-level transport control, compose an assignment-only HTTP client:

{{< code-block lang="dart" >}}
import 'package:http/http.dart' as http;

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.

Issue: This snippet uses withAssignmentRequestTimeout and withAssignmentRequestRetry (lines 321-322) but only imports package:http/http.dart. Copy-pasting will fail to compile because the helpers aren't in scope. Add the package they ship in (likely something like package:datadog_flags/datadog_flags.dart) so the example is complete, matching how the JS example on javascript.md imports withTimeout and withRetry alongside DatadogProvider.


Choose the SDK that matches where the flag is evaluated and initialize the Datadog Feature Flags provider.

<div class="alert alert-warning">Client SDKs do not add a flag assignment request timeout or retry by default, so the underlying platform transport remains authoritative. Configure a bounded timeout of at most 1,500 milliseconds for predictable initialization, and opt in to retries only when appropriate. The browser example below applies a 1,500-millisecond timeout with no retries. The supported SDK guides describe their timeout options and composable transport APIs.</div>

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.

Suggestion: A couple of small clarity issues in this alert:

  • "The supported SDK guides describe their timeout options and composable transport APIs" doesn't link to those guides — from the getting-started page a reader has no direct path to them.
  • "The browser example below" is a bit misleading because the example sits inside tabs; only readers who land on the JavaScript tab see the timeout applied. Consider either applying the same pattern in each tab or rephrasing so the guidance stands on its own regardless of which tab is active.
  • "Opt in to retries only when appropriate" gives the reader no criteria — consider dropping it or briefly stating when retries help (for example, tolerating transient 5xx during initialization).

});
{{< /code-block >}}

In this example, each attempt has a 1.5-second timeout and `2` allows two retries after the initial request. The timeout includes downloading the response body. Set the timeout or retry count to `0` to disable that behavior; retry counts from `0` to `10` are accepted. Retries cover network errors, timeouts, HTTP 408, and HTTP 5xx responses; caller cancellation and HTTP 429 responses are not retried. `flagConfigurationFetch` applies only to flag configuration requests; it does not affect exposure, aggregated flag evaluation, or RUM telemetry requests.

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.

Style: This is a single dense paragraph that mixes timeout semantics, retry semantics, accepted ranges, retry conditions, and scope. Every other SDK page in this PR (Android, iOS, Flutter, Unity) documents the same information as a definition list (one term per option, plus a short scoped-to alert). Consider mirroring that structure here for consistency and scannability — for example, break out withTimeout and withRetry as definition terms and move the "applies only to flag configuration requests" sentence into its own info callout.

@aarsilv aarsilv 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.

Nice! Thanks for getting this out so fast. Approving assuming the code issues caught by GitHub fixed up.

// 3. Enable Feature Flags with a bounded assignment request timeout
Flags.enable(
FlagsConfiguration.Builder()
.assignmentRequestTimeout(1_500L)

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.

🔥

import com.datadog.android.flags.FlagsConfiguration

val flagsConfiguration = FlagsConfiguration.Builder()
.assignmentRequestTimeout(1_500L)

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.

🔥

)..addPlugin(
const DatadogFlagsPluginConfiguration(
flagsConfiguration: DatadogFlagsConfiguration(
assignmentRequestTimeout: Duration(milliseconds: 1500),

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.

🔥


Flags.enable()
var flagsConfiguration = Flags.Configuration()
flagsConfiguration.assignmentRequestTimeout = 1.5

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.

🔥

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.

Ideally the variable would have units, especially since not MS, (e.g., assignmentRequestTimeoutSec) but that is outside the scope of this PR

{{< /code-block >}}

`assignmentRequestTimeout`
: Timeout in seconds for each flag assignment request, including the complete response-body download. The SDK does not add a timeout by default. Set a positive value to enable the timeout; `0` leaves it disabled.

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.

And we cover "seconds" here 👌

});
{{< /code-block >}}

In this example, each attempt has a 1.5-second timeout and `2` allows two retries after the initial request. The timeout includes downloading the response body. Set the timeout or retry count to `0` to disable that behavior; retry counts from `0` to `10` are accepted. Retries cover network errors, timeouts, HTTP 408, and HTTP 5xx responses; caller cancellation and HTTP 429 responses are not retried. `flagConfigurationFetch` applies only to flag configuration requests; it does not affect exposure, aggregated flag evaluation, or RUM telemetry requests.

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.

💪


DdFlags.Enable();
DdFlags.Enable(new FlagsConfiguration(
assignmentRequestTimeoutSeconds: 1,

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.

🔥

@hestonhoffman hestonhoffman added the editorial review Waiting on a more in-depth review label Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

editorial review Waiting on a more in-depth review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants