Skip to content

feat: Wire FDv2 connection-mode resolution in flutter SDK#280

Merged
tanderson-ld merged 10 commits into
mainfrom
ta/SDK-2187/connection-mode-and-resolution-flutter
Jun 4, 2026
Merged

feat: Wire FDv2 connection-mode resolution in flutter SDK#280
tanderson-ld merged 10 commits into
mainfrom
ta/SDK-2187/connection-mode-and-resolution-flutter

Conversation

@tanderson-ld
Copy link
Copy Markdown
Contributor

@tanderson-ld tanderson-ld commented May 29, 2026

Summary

Wires the FDv2 mode-resolution machinery into the Flutter SDK's ConnectionManager. Stacked on the common_client PR (#279); rebase onto main once that merges.

This is the second half of the further split of the original behavior PR (#275, now closed).

ConnectionManager

  • DartClientAdapter forwards ResolvedConnectionMode to LDCommonClient.setResolvedMode (the new advanced FDv2 entry point from feat: Wire FDv2 connection-mode resolution in common_client #279).
  • ConnectionManagerConfig.backgroundConnectionMode (new) is typed FDv2ConnectionMode. initialConnectionMode stays ConnectionMode (legacy).
  • disableAutomaticBackgroundHandling keeps its original name.
  • Automatic mode resolution uses resolveMode + flutterDefaultResolutionTable; setMode override path supports the 3 FDv1 modes only (background is auto-resolved, not user-selectable).

Flutter umbrella re-exports cover the FDv2 types consumed by this PR (FDv2ConnectionMode + four subtypes, ResolvedConnectionMode family, OfflineDetail family, ModeState/ModeResolutionEntry/resolveMode/flutterDefaultResolutionTable).

Platform defaults (io_config / js_config / stub_config / flutter_default_config) return FDv2ConnectionMode for the background slot.

LDClient passes backgroundConnectionMode to the ConnectionManager and sets offline=true post-construction (no longer forces initial mode to offline in config).

Tests updated to match.

Depends on #279 -- the LDCommonClient.setResolvedMode method this PR consumes lives there.


Note

Medium Risk
Connection and data-source behavior changes across foreground/background and network transitions (including new status reasons and mobile background polling), which can affect flag freshness and event delivery even though public FDv1 setMode remains.

Overview
Flutter ConnectionManager now picks a ResolvedConnectionMode from app foreground/background, network, config, and optional overrides using resolveMode and flutterDefaultResolutionTable (custom tables supported). It forwards modes through DartClientAdapter.setResolvedMode, adds backgroundConnectionMode, and setMode(FDv2ConnectionMode?) for manual override. Background transitions still flush events; event sending rules are tied to offline / background + runInBackground.

common_client DataSourceManager is keyed on FDv2ConnectionMode factories and setMode(ResolvedConnectionMode), mapping offline OfflineDetail to setOffline / setNetworkUnavailable / setBackgroundDisabled. LDCommonClient composes FDv1 factories into FDv2 (including an SDK-managed background polling factory), exposes setResolvedMode, and stops pushing network availability into the data source manager (Flutter resolves network loss to ResolvedOffline(OfflineNetworkUnavailable) instead).

Platform defaults: mobile uses FDv2Background and enables automatic background/network handling by default; desktop and web default the background slot to offline and disable those detectors unless configured. LDClient passes the platform background slot and sets ConnectionManager.offline after build when config.offline. FDv2 types are re-exported from the Flutter package; launchdarkly_common_client is bumped to 1.11.0.

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

Wires the FDv2 mode-resolution scaffolding (merged via #274) into the
common_client runtime path while keeping the FDv1 ConnectionMode enum
and all existing public API signatures unchanged.

LDCommonClient:
- setMode(ConnectionMode) keeps its FDv1 signature and now maps the 3
  legacy modes to ResolvedConnectionMode internally before forwarding
  to DataSourceManager.
- New setResolvedMode(ResolvedConnectionMode) is the advanced FDv2
  entry point. Documented as EAP / not-stable. No internal caller in
  this PR; the Flutter SDK's ConnectionManager invokes it in the
  follow-up flutter PR.
- DataSourceFactoriesFn (the public, optional constructor seam)
  remains typed Map<ConnectionMode, DataSourceFactory> so external
  callers can still customize streaming + polling. _backgroundFactory
  is SDK-managed (background is FDv2-only), and
  _composeFactoriesForManager translates the FDv1 map into the
  FDv2-keyed Map<FDv2ConnectionMode, DataSourceFactory> consumed by
  DataSourceManager.

DataSourceManager (internal, not publicly exported):
- Active mode held as ResolvedConnectionMode.
- Factory map is keyed by FDv2ConnectionMode.
- ResolvedOffline branches dispatch status as setOffline /
  networkUnavailable / backgroundDisabled depending on OfflineDetail.

Tests updated to match.
Wires the FDv2 mode-resolution machinery (from common_client) into the
Flutter SDK's ConnectionManager while preserving all existing public
API signatures.

ConnectionManager:
- DartClientAdapter forwards ResolvedConnectionMode to
  LDCommonClient.setResolvedMode (the new advanced FDv2 entry point).
- ConnectionManagerConfig.backgroundConnectionMode (new) is typed
  FDv2ConnectionMode; initialConnectionMode stays ConnectionMode
  (legacy).
- disableAutomaticBackgroundHandling keeps its original name.
- Automatic mode resolution uses resolveMode +
  flutterDefaultResolutionTable; setMode override path supports the 3
  FDv1 modes only (background is auto-resolved, not user-selectable).

Flutter umbrella re-exports cover the FDv2 types consumed by this PR
(FDv2 connection-mode subtypes, ResolvedConnectionMode family,
OfflineDetail family, ModeState/ModeResolutionEntry/resolveMode/
flutterDefaultResolutionTable).

Platform defaults (io_config / js_config / stub_config /
flutter_default_config) return FDv2ConnectionMode for the background
slot.

LDClient passes backgroundConnectionMode to the ConnectionManager and
sets offline=true post-construction (no longer forces initial mode to
offline in config).

Tests updated to match.

Depends on the LDCommonClient.setResolvedMode addition in the
predecessor common-only PR.
tanderson-ld and others added 3 commits May 29, 2026 11:12
Splits the active mode and offline detail into two fields:

- _activeConnectionMode: FDv2ConnectionMode -- drives factory lookup
  (matches the factory map's key type directly).
- _offlineDetail: OfflineDetail -- semantically meaningful only when
  _activeConnectionMode is FDv2Offline; carries a stale value in
  other modes and is intentionally only read inside the FDv2Offline
  arm of _setupConnection.

ResolvedConnectionMode is now a true boundary type: consumed by
setMode, decomposed into the two fields, then discarded. This
removes the .connectionMode getter call previously needed for
factory lookup.

setMode dedup is rewritten to compare the FDv2 mode and (when
offline) the offline detail explicitly, so a redundant call with
the same effective state still short-circuits.

Constructor initializes _offlineDetail to OfflineSetOffline() as a
placeholder; it is overwritten the next time setMode receives a
ResolvedOffline value.
… ta/SDK-2187/connection-mode-and-resolution-flutter
/// The initial connection mode the SDK should use.
/// Configured foreground connection mode used as the automatic resolution
/// foreground slot.
final ConnectionMode initialConnectionMode;
Copy link
Copy Markdown
Contributor Author

@tanderson-ld tanderson-ld May 29, 2026

Choose a reason for hiding this comment

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

This is ok if initialConnectionMode is never expected to be background. The asymmetry between initialConnectionMode and backgroundConnectionMode isn't great, but it would require a breaking change to make them symmetric. Thoughts?

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.

As long as when you disable handling for lifecycle and network we use this mode.
I don't see symmetry as a consideration, but that it can do the things you need it to do.

Is this just a change in comment, or is there a functionality change here as well?

The runtime mode-override path now uses FDv2ConnectionMode end-to-end:

- ConnectionManager._modeOverride is FDv2ConnectionMode? (was
  ConnectionMode?).
- ConnectionManager.setMode signature accepts FDv2ConnectionMode? so
  callers can request any FDv2 mode -- including FDv2Background() --
  as the override.
- _handleState pattern-matches the four FDv2 subtypes when applying
  the override.

initialConnectionMode stays ConnectionMode (FDv1) because it is bound
to LDConfig.dataSourceConfig.initialConnectionMode, an existing
user-visible configuration field. The _fdv2FromFdv1 helper retains
its remaining caller (translating initialConnectionMode into the
ModeState slot).

Tests updated. The override iteration in 'given requested connection
modes' now exercises all four FDv2 modes (background included).
@tanderson-ld tanderson-ld marked this pull request as ready for review May 29, 2026 20:16
@tanderson-ld tanderson-ld requested a review from a team as a code owner May 29, 2026 20:16
… ta/SDK-2187/connection-mode-and-resolution-flutter
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ 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 4418f37. Configure here.

Comment thread packages/flutter_client_sdk/lib/src/ld_client.dart
Base automatically changed from ta/SDK-2187/connection-mode-and-resolution-common to main June 3, 2026 19:30
The FDv2 connection-mode resolution wiring on this branch consumes APIs
introduced in launchdarkly_common_client 1.10.0 (FDv2ConnectionMode +
subtypes, ResolvedConnectionMode family) and 1.11.0
(LDCommonClient.setResolvedMode). Bump the pinned exact version to
match so published flutter_client_sdk releases resolve against a
common_client that actually has these symbols.
@tanderson-ld tanderson-ld merged commit ef8ad39 into main Jun 4, 2026
7 checks passed
@tanderson-ld tanderson-ld deleted the ta/SDK-2187/connection-mode-and-resolution-flutter branch June 4, 2026 00:26
tanderson-ld pushed a commit that referenced this pull request Jun 4, 2026
🤖 I have created a release *beep* *boop*
---


##
[1.12.0](launchdarkly_common_client-v1.11.0...launchdarkly_common_client-v1.12.0)
(2026-06-04)


### Features

* Wire FDv2 connection-mode resolution in flutter SDK
([#280](#280))
([ef8ad39](ef8ad39))

---
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]
> **Low Risk**
> Version and changelog-only release with no code diffs in this PR.
> 
> **Overview**
> Release Please bumps **`launchdarkly_common_client`** from **1.11.0**
to **1.12.0** with matching updates to `.release-please-manifest.json`
and `packages/common_client/pubspec.yaml`.
> 
> The new **1.12.0** changelog section documents FDv2 connection-mode
resolution wired through the Flutter SDK ([#280]); this PR does not
include application or library source changes—only version and release
notes.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
54d95d7. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
tanderson-ld pushed a commit that referenced this pull request Jun 4, 2026
🤖 I have created a release *beep* *boop*
---


##
[4.17.0](4.16.0...4.17.0)
(2026-06-04)


### Features

* Wire FDv2 connection-mode resolution in flutter SDK
([#280](#280))
([ef8ad39](ef8ad39))

---
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]
> **Low Risk**
> Version and changelog-only changes from Release Please; no new runtime
logic in this diff.
> 
> **Overview**
> **Release 4.17.0** for `launchdarkly_flutter_client_sdk`: bumps the
package and example app from **4.16.0 → 4.17.0**, updates
`.release-please-manifest.json`, and sets the reported `sdkVersion` in
`ld_client.dart`.
> 
> The changelog entry records the shipped feature from
[#280](#280):
**FDv2 connection-mode resolution** wired through the Flutter SDK (no
additional implementation changes appear in this diff).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
cd9dc43. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
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