chore: adds connection mode resolution and source factories#265
chore: adds connection mode resolution and source factories#265tanderson-ld wants to merge 11 commits into
Conversation
Implements the four building blocks Phase 3 needs from Stream A: - calculate_poll_delay.dart: pure helper. Given freshness and interval, returns the time remaining in the interval; zero when overdue; full interval when there's no prior freshness or the freshness is in the future (clock skew clamp). - polling_initializer.dart: one-shot Initializer. Calls the injected PollFunction up to 3 times. ChangeSetResult and terminal status results return immediately. Interrupted results retry after a 1s delay. After 3 interrupted attempts the last is escalated to terminalError so the orchestrator stops retrying at this layer. close() interrupts a pending retry delay and yields shutdown. - polling_synchronizer.dart: long-lived Synchronizer. Single- subscription StreamController that polls immediately on subscribe, then schedules subsequent polls via calculatePollDelay over the freshness of the most recent successful result. Interrupted results pass through but do not advance freshness, so a transient failure does not delay the catch-up poll. Injected TimerFactory and now() for deterministic tests. - cache_initializer.dart: Initializer that reads the persistence cache via an injected CachedFlagsReader. Cache hit emits a full ChangeSetResult with persist=false and an empty selector (the cache does not track server-side selector state). Cache miss or reader exception emits a none-type ChangeSetResult so the initializer chain advances. The reader typedef leaves the actual persistence wiring to the orchestrator (Phase C1). PollFunction, DelayFunction, TimerFactory, and CachedFlagsReader are typedefs rather than concrete dependencies so the orchestrator can wire real implementations and tests can inject scripted ones, mirroring the abstraction style established in SDK-2183.
- polling_synchronizer: replace `bool _closed` with `Completer<void> _stoppedSignal` to match the polling initializer and have a single source of truth for closed-ness. Drop the redundant `_controller.isClosed` checks (the signal is set before the controller is closed, so the signal check covers both cases). Replace `Future<void>.microtask(_doPoll)` in onListen with `unawaited(_doPoll())` -- the microtask wrapping was unnecessary; fire-and-forget of an async function is what unawaited expresses. - polling_synchronizer: fix typo in the unexpected-throw message: "raised unexpectedly" -> "raised error unexpectedly". - calculate_poll_delay: split the run-on docstring describing the null-freshness and overdue-freshness cases into two separate sentences for readability. - cache_initializer: reword the awkward parenthetical "(the data came from the cache; writing it back is a no-op)" to "(the data is already cached)".
…king branch 'origin' into ta/SDK-2187/connection-mode-and-resolution
|
Need to bench test to confirm no regressions in connection manager wrt event flushing. |
…tion to drive status reporting
2275df1 to
2f1cd6e
Compare
|
Need to investigate broken tests. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default mode and found 2 potential issues.
❌ 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 d8bce6d. Configure here.
| ConnectionMode.background => const ResolvedBackground(), | ||
| ConnectionMode.offline => const ResolvedOffline(OfflineSetOffline()), | ||
| }; | ||
| } |
There was a problem hiding this comment.
Background-slot offline misreports status as user-set-offline
Medium Severity
_resolvedFromConnectionMode(ConnectionMode.offline) always produces OfflineSetOffline(), even when called from the resolution table's background-slot row (_backgroundSlotResolved). When runInBackground=true and backgroundConnectionMode is ConnectionMode.offline, the DataSourceManager reports DataSourceState.setOffline — implying the user explicitly set the SDK offline — rather than a status that reflects automatic background resolution. Consumers monitoring DataSourceStatus will see a misleading state change that looks like an explicit offline toggle rather than an automatic lifecycle transition.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d8bce6d. Configure here.
| ResolvedPolling, | ||
| ResolvedBackground, | ||
| ResolvedOffline, | ||
| resolveMode, |
There was a problem hiding this comment.
Flutter SDK exports unusable resolveMode without parameter types
Low Severity
The Flutter SDK re-exports resolveMode but does not re-export ModeState, ModeResolutionEntry, or flutterDefaultResolutionTable (which are all exported from common_client). Since resolveMode requires List<ModeResolutionEntry> and ModeState as parameters, it is effectively unusable by Flutter SDK consumers without a direct import of the common_client package. Either the supporting types and the default table factory need to be re-exported alongside resolveMode, or resolveMode should not be exported from the Flutter SDK.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit d8bce6d. Configure here.


Requirements
Note
Medium Risk
Changes core connection/data-source switching behavior by introducing automatic mode resolution (foreground/background/network) and a new
ResolvedConnectionModeAPI; mistakes could cause incorrect online/offline status or unnecessary disconnects, though coverage is added.Overview
Introduces a richer connection-mode model by adding
ConnectionMode.background,ResolvedConnectionMode(includingResolvedOfflinewithOfflineDetail), and exporting these new types from the public APIs.Updates the common client and
DataSourceManagerto operate on resolved modes (removing direct network-availability-driven switching) and to map specific offline reasons to distinct data source statuses (setOffline,networkUnavailable,backgroundDisabled).Adds Flutter automatic mode resolution via
ModeState/resolveModewith a default resolution table and platform-specific defaults for background behavior, plus FDv2 helpers (ModeDefinition, built-in mode definitions,SourceFactoryContext, and entry-to-factory builders with per-entry endpoint overrides). Test suites are expanded/updated to cover the new resolution behavior, background factory wiring, and factory/context utilities.Reviewed by Cursor Bugbot for commit d8bce6d. Bugbot is set up for automated code reviews on this repo. Configure here.