feat: add Initializer and Synchronizer source contracts #259
Draft
kinyoklion wants to merge 5 commits intomainfrom
Draft
feat: add Initializer and Synchronizer source contracts #259kinyoklion wants to merge 5 commits intomainfrom
kinyoklion wants to merge 5 commits intomainfrom
Conversation
Adds source.dart with the Initializer/Synchronizer interfaces and the SelectorGetter/PingHandler typedefs. These are the contracts for FDv2 data sources: Initializer for one-shot results, Synchronizer for streaming results, SelectorGetter for lazy selector reads, and PingHandler for legacy ping-driven polls. Concrete implementations follow in subsequent commits.
Adds the HTTP layer for FDv2 polling: - endpoints.dart: FDv2 polling and streaming path constants, uniform across mobile and browser. - requestor.dart: FDv2Requestor — pure HTTP. Builds GET URLs with the encoded context in the path or POST URLs with the context JSON in the body. Adds basis (when the selector is non-empty) and withReasons query params. Tracks ETag across requests via if-none-match. Returns a RequestorResponse record. - polling_base.dart: FDv2PollingBase — wraps the requestor with FDv2 protocol semantics. Network errors produce interrupted; the x-ld-fd-fallback header produces terminalError with fdv1Fallback set; 304 produces a none-type ChangeSetResult; recoverable 4xx/5xx produce interrupted; non-recoverable 4xx produce terminalError; 200 bodies are parsed as FDv2EventsCollection and run through a fresh FDv2ProtocolHandler. No data source integration yet — that follows in SDK-2184.
Fixes from review of PR #259: - pollOnce now honors its 'never throws' contract: widen the try/catch in _parseBody to cover the FDv2EventsCollection.fromJson cast and per-event fromJson casts. Malformed event shapes (non-Map elements in events/payloads, wrong-type object fields) return interrupted instead of propagating a TypeError. - ETag is now persisted only on 200. A 5xx with an ETag could otherwise poison the next request and cause a follow-up 304 to be misclassified as 'cache is current' even when the SDK has no successful payload. A 304 leaves the existing ETag alone (it confirms the stored value). - URL building uses Uri parsing instead of string concatenation, so custom polling URLs with embedded query parameters (e.g. a relay proxy with a token) are preserved correctly. Our query params merge with the base URL's. - Network exception messages no longer echo into the public StatusResult.message. They are categorized into fixed strings (Network/TLS/Timeout); the full err.toString() stays in the warn log only. SocketException, TlsException, and HandshakeException details (remote IP, cert CN, OS error codes) no longer surface on dataSourceStatus.lastError.message. - x-ld-fd-fallback header is matched case-insensitively. Doc notes that the header takes precedence over body and status code. - Debug log line no longer interpolates the full URL (which embeds the base64url-encoded context in GET mode). - HTTP error paths (4xx / 5xx) now log warn/error like the network and JSON parse paths do. - FDv2Endpoints.streaming doc now reflects that the constant serves both POST and GET (via streamingGet). - FDv2Requestor doc states the serial-only contract for request(). - Defensive guard in the requestor: basis is omitted when the selector's state string is empty, even if isEmpty=false (covers Selector(state: '', version: N)). New tests cover malformed event shapes, ETag handling on 4xx/5xx and 304, custom polling URL with query parameters, basis/withReasons on POST mode, fallback header precedence over 200/304, case- insensitive header matching, intent-none on 200, heartbeat-only response, and exception-message sanitization.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
BEGIN_COMMIT_OVERRIDE
feat: add Initializer and Synchronizer source contracts
feat: add FDv2 requestor and polling base
END_COMMIT_OVERRIDE
Adds the HTTP layer for FDv2 polling, plus the Initializer and Synchronizer contracts that future polling and streaming sources will implement.
The requestor is a thin HTTP wrapper: builds the URL, sends GET (context in path) or POST (context in body), tracks ETag for if-none-match, and returns a
response record. It knows nothing about the FDv2 protocol.
The polling base wraps the requestor with FDv2 semantics: classifies HTTP errors as interrupted vs terminal, treats 304 as a no-op change set, detects the
x-ld-fd-fallback header, and runs the response body through a fresh protocol handler to produce an FDv2SourceResult.