You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Wires the recovery half of the FDv1 fallback directive: once the SDK has fallen back to FDv1, it now schedules an unconditional, elapsed-time attempt to return to FDv2 once the fallback TTL elapses, using the fdv2Recovery() / isCurrentSynchronizerFDv1Fallback primitives added in #1856.
Also corrects the shared fallbackDirective.ts's TTL handling to match the spec: an absent, unparseable, negative, or out-of-range TTL (including 0, previously treated as indefinite fallback) now clamps to a jittered 1-hour default instead. A server-supplied in-range TTL is used as-is. Directed fallback is therefore never indefinite.
FDv2RecoveryTimer is a new standalone primitive holding that single deadline; it is not modeled as a Condition since getConditions() produces nothing when the SDK has one or zero available synchronizers, which is exactly the state a directed fallback creates. In FDv2DataSource, the deadline races the active synchronizer loop, and if every synchronizer slot is blocked before the deadline fires, a background continuation takes over responsibility for the timer and restarts FDv2 sources on its own once it elapses -- without holding up the in-flight start()/identify() call.
Note
Overview After the server directs an FDv1 fallback, the SDK now schedules an unconditional return to FDv2 when the directive TTL elapses, instead of staying on FDv1 indefinitely when TTL was missing or zero.
Shared resolveFallbackTtlMs (and exports of DEFAULT_FDV1_FALLBACK_TTL_MS) replace prior behavior: only TTLs in (0, 1 hour] are honored as given; missing, invalid, zero, negative, or over-one-hour values become a jittered one-hour default, so directed fallback always has a concrete retry deadline. Header and goodbye protocolFallbackTTL parsing both route through this helper.
FDv2RecoveryTimer holds that single deadline; FDv2DataSource arms it on every fallback directive (including while already on the FDv1 synchronizer—reschedule only), races it in the synchronizer loop, and calls sourceManager.fdv2Recovery() when it fires. If all synchronizer slots are blocked but a deadline remains, a background continuation keeps the timer alive and restarts FDv2 without blocking start() resolution; close() and orchestration teardown cancel or hand off the timer appropriately.
Reviewed by Cursor Bugbot for commit ec977f2. Bugbot is set up for automated code reviews on this repo. Configure here.
@launchdarkly/js-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 27419 bytes
Compressed size limit: 29000
Uncompressed size: 132948 bytes
@launchdarkly/js-client-sdk size report
This is the brotli compressed size of the ESM build.
Compressed size: 32929 bytes
Compressed size limit: 34000
Uncompressed size: 117914 bytes
@launchdarkly/js-client-sdk-common size report
This is the brotli compressed size of the ESM build.
Compressed size: 25830 bytes
Compressed size limit: 44000
Uncompressed size: 168499 bytes
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
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.
Summary
Wires the recovery half of the FDv1 fallback directive: once the SDK has fallen back to FDv1, it now schedules an unconditional, elapsed-time attempt to return to FDv2 once the fallback TTL elapses, using the
fdv2Recovery()/isCurrentSynchronizerFDv1Fallbackprimitives added in #1856.Also corrects the shared
fallbackDirective.ts's TTL handling to match the spec: an absent, unparseable, negative, or out-of-range TTL (including0, previously treated as indefinite fallback) now clamps to a jittered 1-hour default instead. A server-supplied in-range TTL is used as-is. Directed fallback is therefore never indefinite.FDv2RecoveryTimeris a new standalone primitive holding that single deadline; it is not modeled as aConditionsincegetConditions()produces nothing when the SDK has one or zero available synchronizers, which is exactly the state a directed fallback creates. InFDv2DataSource, the deadline races the active synchronizer loop, and if every synchronizer slot is blocked before the deadline fires, a background continuation takes over responsibility for the timer and restarts FDv2 sources on its own once it elapses -- without holding up the in-flightstart()/identify()call.Note
Overview
After the server directs an FDv1 fallback, the SDK now schedules an unconditional return to FDv2 when the directive TTL elapses, instead of staying on FDv1 indefinitely when TTL was missing or zero.
Shared
resolveFallbackTtlMs(and exports ofDEFAULT_FDV1_FALLBACK_TTL_MS) replace prior behavior: only TTLs in (0, 1 hour] are honored as given; missing, invalid, zero, negative, or over-one-hour values become a jittered one-hour default, so directed fallback always has a concrete retry deadline. Header and goodbyeprotocolFallbackTTLparsing both route through this helper.FDv2RecoveryTimerholds that single deadline;FDv2DataSourcearms it on every fallback directive (including while already on the FDv1 synchronizer—reschedule only), races it in the synchronizer loop, and callssourceManager.fdv2Recovery()when it fires. If all synchronizer slots are blocked but a deadline remains, a background continuation keeps the timer alive and restarts FDv2 without blockingstart()resolution;close()and orchestration teardown cancel or hand off the timer appropriately.Reviewed by Cursor Bugbot for commit ec977f2. Bugbot is set up for automated code reviews on this repo. Configure here.