feat: Thread FDv1 fallback TTL through polling and streaming data sources#1806
feat: Thread FDv1 fallback TTL through polling and streaming data sources#1806joker23 wants to merge 10 commits into
Conversation
|
@launchdarkly/js-sdk-common size report |
|
@launchdarkly/js-client-sdk-common size report |
|
@launchdarkly/js-client-sdk size report |
|
@launchdarkly/browser size report |
|
@cursor review |
e4fa9cb to
1400310
Compare
|
@cursor review |
46de8d4 to
6604149
Compare
|
@cursor review |
|
@cursor review |
29aefb7 to
73eeb30
Compare
|
@cursor review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit c01baaa. Configure here.
| terminalError, | ||
| } from './FDv2SourceResult'; | ||
|
|
||
| function getFallback(headers: { get(name: string): string | null }): boolean { |
There was a problem hiding this comment.
replacing with
| fdv1FallbackTtlMs = pendingFallbackTtlMs; | ||
| resultQueue.put(changeSet(action.payload, true, undefined, undefined, pendingFallbackTtlMs)); | ||
| pendingFallback = false; | ||
| pendingFallbackTtlMs = undefined; |
There was a problem hiding this comment.
Should this section use resolveFallback?
| case 'payload': | ||
| logConnectionResult(true); | ||
| resultQueue.put(changeSet(action.payload, fdv1Fallback)); | ||
| if (pendingFallback) { |
There was a problem hiding this comment.
Is this if check required? Is there a way to write it such that it just uses resolveFallback always?
| fdv1Fallback = true; | ||
| resultQueue.put(terminalError(errorInfoFromUnknown(action.reason), true, ttlMs)); | ||
| pendingFallback = false; | ||
| pendingFallbackTtlMs = undefined; |
There was a problem hiding this comment.
Same comment here. I thought the purpose of the resolveFallback was to remove duplication of this routine of consuming the pending fallback and clearing values.
| const fallback = resolveFallback(); | ||
| if (!result.fdv1Fallback && fallback.fdv1Fallback) { | ||
| result.fdv1Fallback = true; | ||
| result.fdv1FallbackTtlMs = fallback.fdv1FallbackTtlMs; |
There was a problem hiding this comment.
Is editing result appropriate? Seems like it shouldn't be mutated from a good practices standpoint.
There was a problem hiding this comment.
Something feels off about how many spots have if checks on pending fallback and logic for moving things around and masking values on top of others. It just seems very scattered and likely a subtle tweak will mess up the logic. Is there a way to make it such that all results that go into the queue conform to some type / interface and fallback can be applied to that thing unconditonally, sometimes a no-op but sometimes a real fallback apply occurs. The pending mechanism could be something that can only apply once and then turns itself into a no-op or something.
…rces This commit will add in fallback TTL reading support as well as allow RN native event source read headers.
e95c2f2 to
005c842
Compare
This will allow us to resolve directives that should override the fallback behavior such as goodbye or error
005c842 to
adfcb4d
Compare
This commit will add in fallback TTL reading support as well as allow RN native event source read headers.
NOTE: while working this PR, I found a lot of gaps in the RN eventsource. Internally tracked in ticket 2721 in sdk project.
Note
Medium Risk
Changes how FDv2 sources signal and time FDv1 fallback (including goodbye vs terminal_error), which affects orchestrator source switching; scope is large but heavily tested.
Overview
Adds a shared
FallbackDirectivemodel and header/event parsers so FDv2 polling and streaming can carryfdv1Fallbackplusfdv1FallbackTtlMs(fromx-ld-fd-fallback/x-ld-fd-fallback-ttl, or in-bandprotocolFallbackTTLon goodbye).Result builders (
changeSet,interrupted,terminalError,goodbye) now take a directive object instead of a bare boolean; call sites and tests are updated accordingly. Polling reads the directive on every response and, when fallback is set alongside a goodbye event, emitsterminal_errorso the orchestrator switches off FDv2 instead of treating it as a benign goodbye. Streaming defers open-header directives until the next queued result, merges them into errors/ping paths without mutating ping handler objects, and clears pending/committed fallback state on reconnect andclose. Polling initializer keeps fallback + TTL when retries exhaust.CI package size limit for
@launchdarkly/js-client-sdk-commonis raised to 41500 bytes.Reviewed by Cursor Bugbot for commit 20081c8. Bugbot is set up for automated code reviews on this repo. Configure here.