-
Notifications
You must be signed in to change notification settings - Fork 4
feat: add FDv2 configuration builder #545
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
beekld
wants to merge
51
commits into
main
Choose a base branch
from
beeklimt/SDK-2100
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
51 commits
Select commit
Hold shift + click to select a range
5ce3fda
feat: orchestrator switches to FDv1 fallback on directive
beekld 77c972f
chore: add orchestration logging for FDv2 data system
beekld 5a2a9bc
fix: stop emitting kOff status from FDv2DataSystem destructor
beekld 86b2e3d
feat: add FDv1AdapterSynchronizer wrapping IDataSynchronizer as IFDv2…
beekld 8cc95b6
feat: add FDv2 configuration builder
beekld cdaec02
feat: add FDv1 polling overload to FDv2Builder::FDv1Fallback
beekld b3690ca
feat: variadic synchronizers, initializers, and per-source endpoint o…
beekld 62709ec
test: update FDv2 URL tests to match refactored signatures
beekld a39b086
refactor: split FDv1 and FDv2 streaming/polling configs
beekld 9bb657e
refactor: FDv2Builder starts empty; add Default() for spec config
beekld f99f1ad
chore: distinguish engaged vs. unconfigured FDv1 fallback in logs
beekld 82d2730
fix: ignore FDv1 fallback directive when FDv1 source is active
beekld c164913
test: cover initializer ChangeSet+directive basis preservation
beekld 44f47f4
feat: parse X-LD-FD-Fallback-TTL header into FDv2SourceResult
beekld 6ca1a49
feat: parse protocolFallbackTTL and retryAfter from goodbye
beekld 8f19a0e
feat: schedule FDv2 retry after FDv1 fallback TTL
beekld 5b9e51e
merge: bring in FDv1 fallback TTL changes from #539
beekld 407bc56
merge: bring in FDv1 fallback TTL changes from #540
beekld e1a9969
test: adapt new TTL streaming tests to 545's endpoint signature
beekld 303b3a8
chore: remove unused retry_after field from goodbye
beekld 7f1e999
merge: pick up retry_after removal from #539
beekld c22e53d
merge: pick up retry_after removal from #540
beekld b1157e1
feat: translate FDv1 status changes to FDv2 results in FDv1AdapterSyn…
beekld 638babc
merge: pick up FDv1 status translation from #540
beekld b2eae57
fix: pass status manager to FDv1AdapterSynchronizer
beekld 9a93aab
docs: explain got_basis reuse in FDv1 fallback branch
beekld 67126a9
fix: reset FDv1 fallback retry source between schedules
beekld 81b1c7f
merge: pick up OpenSSL bump from main
beekld 373150d
merge: pick up OpenSSL bump from #539
beekld 71c202c
merge: pick up OpenSSL bump from #540
beekld 292c779
merge: pick up #539 squash from main
beekld 7afaf7e
merge: pick up #539 squash from #540
beekld 27f5c1e
fix: serialize StartAsync/ShutdownAsync on wrapped FDv1 source
beekld dab36f4
merge: pick up FDv1 source lifecycle fix from #540
beekld 6c428c5
fix: give FDv1 adapter a private status manager
beekld 55bd262
merge: pick up #549 from main
beekld 7d01543
merge: pick up FDv1 adapter status sink fix from #540
beekld d759139
fix: wire FDv1 adapter factories to new private-status-manager API
beekld 2f68933
fix: hold FDv1 source via shared_ptr and forward init-time errors
beekld 937bf4a
merge: pick up shared_ptr/init-error fixes from #540
beekld 1524301
fix: construct FDv1 sources via make_shared for enable_shared_from_this
beekld 796d25c
merge: pick up #550 from main
beekld 15f5d5d
merge: pick up #550 from #540
beekld 83a5e4d
fix: handle FDv2 intentCode none as listening, reject unknown codes
beekld 68c95ef
merge: pick up intentCode none fix from #555
beekld f40b13f
merge: pick up main after #540 squash
beekld 1b6f086
merge: pick up main after #540 squash from #555
beekld 3cadda8
merge: pick up main after #555 squash
beekld 13bdf20
docs: correct DisableFDv1Fallback comment to match actual behavior
beekld 41b797e
merge: pick up #552 from main
beekld 45f5926
refactor: replace public FDv2Builder ctor with Custom() factory
beekld File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
145 changes: 145 additions & 0 deletions
145
.../server-sdk/include/launchdarkly/server_side/config/builders/data_system/fdv2_builder.hpp
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| #pragma once | ||
|
|
||
| #include <launchdarkly/config/shared/builders/data_source_builder.hpp> | ||
| #include <launchdarkly/config/shared/sdks.hpp> | ||
| #include <launchdarkly/server_side/config/built/data_system/fdv2_config.hpp> | ||
|
|
||
| #include <chrono> | ||
| #include <optional> | ||
| #include <string> | ||
|
|
||
| namespace launchdarkly::server_side::config::builders { | ||
|
|
||
| class FDv2Builder { | ||
| public: | ||
| class Streaming { | ||
| public: | ||
| Streaming& InitialReconnectDelay(std::chrono::milliseconds delay); | ||
| Streaming& Filter(std::string filter_key); | ||
| Streaming& BaseUrl(std::string base_url); | ||
| [[nodiscard]] built::FDv2Config::StreamingConfig Build() const; | ||
|
|
||
| private: | ||
| std::chrono::milliseconds initial_reconnect_delay_{1000}; | ||
| std::optional<std::string> filter_key_; | ||
| std::optional<std::string> base_url_override_; | ||
| }; | ||
|
|
||
| class Polling { | ||
| public: | ||
| Polling& PollInterval(std::chrono::seconds interval); | ||
| Polling& Filter(std::string filter_key); | ||
| Polling& BaseUrl(std::string base_url); | ||
| [[nodiscard]] built::FDv2Config::PollingConfig Build() const; | ||
|
|
||
| private: | ||
| std::chrono::seconds poll_interval_{30}; | ||
| std::optional<std::string> filter_key_; | ||
| std::optional<std::string> base_url_override_; | ||
| }; | ||
|
|
||
| /** | ||
| * @return A builder pre-populated with the spec-recommended initializers, | ||
| * synchronizers, and FDv1 fallback. Equivalent to calling | ||
| * Initializer(), Synchronizer(), and FDv1Fallback() with the | ||
| * standard sources. | ||
| */ | ||
| static FDv2Builder Default(); | ||
|
|
||
| /** | ||
| * @return A builder with no initializers, no synchronizers, and no | ||
| * FDv1 fallback. Callers must add sources explicitly. | ||
| */ | ||
| static FDv2Builder Custom(); | ||
|
|
||
| /** | ||
| * @brief Appends a polling initializer to the initializers list. | ||
| * @param source Polling source configuration for the initializer. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& Initializer(Polling source); | ||
|
|
||
| /** | ||
| * @brief Appends a streaming synchronizer to the synchronizers list. | ||
| * Order in the list determines preference: the first entry is the | ||
| * primary synchronizer, subsequent entries are fallbacks. | ||
| * @param source Streaming source configuration. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& Synchronizer(Streaming source); | ||
|
|
||
| /** | ||
| * @brief Appends a polling synchronizer to the synchronizers list. See | ||
| * Synchronizer(Streaming) for ordering semantics. | ||
| * @param source Polling source configuration. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& Synchronizer(Polling source); | ||
|
|
||
| using FDv1Streaming = | ||
| launchdarkly::config::shared::builders::StreamingBuilder< | ||
| launchdarkly::config::shared::ServerSDK>; | ||
| using FDv1Polling = launchdarkly::config::shared::builders::PollingBuilder< | ||
| launchdarkly::config::shared::ServerSDK>; | ||
|
|
||
| /** | ||
| * @brief Configures the FDv1 streaming source used as a last-resort | ||
| * fallback when the LaunchDarkly service signals (via the | ||
| * X-LD-FD-Fallback header) that the SDK should switch to FDv1. The | ||
| * fallback reads its endpoint from the top-level ServiceEndpoints; to | ||
| * point the fallback at a custom URL, configure ServiceEndpoints | ||
| * accordingly. | ||
| * @param source FDv1 streaming source configuration. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& FDv1Fallback(FDv1Streaming source); | ||
|
|
||
| /** | ||
| * @brief Configures the FDv1 polling source used as a last-resort | ||
| * fallback when the LaunchDarkly service signals (via the | ||
| * X-LD-FD-Fallback header) that the SDK should switch to FDv1. The | ||
| * fallback reads its endpoint from the top-level ServiceEndpoints; to | ||
| * point the fallback at a custom URL, configure ServiceEndpoints | ||
| * accordingly. | ||
| * @param source FDv1 polling source configuration. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& FDv1Fallback(FDv1Polling source); | ||
|
|
||
| /** | ||
| * @brief Disables the FDv1 fallback. After this call, an FDv1 | ||
| * fallback directive from the service leaves the data source in | ||
| * the interrupted state and schedules an FDv2 retry on the | ||
| * directive's TTL. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& DisableFDv1Fallback(); | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| /** | ||
| * @brief Sets how long the active synchronizer may remain interrupted | ||
| * before the orchestrator falls back to the next-preferred synchronizer. | ||
| * @param timeout Duration the synchronizer must be continuously | ||
| * interrupted for before fallback fires. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& FallbackTimeout(std::chrono::milliseconds timeout); | ||
|
|
||
| /** | ||
| * @brief Sets how long a fallback synchronizer must run successfully | ||
| * before the orchestrator attempts to recover to the primary | ||
| * synchronizer. | ||
| * @param timeout Duration the fallback synchronizer must run before a | ||
| * recovery attempt is made. | ||
| * @return Reference to this. | ||
| */ | ||
| FDv2Builder& RecoveryTimeout(std::chrono::milliseconds timeout); | ||
|
|
||
| [[nodiscard]] built::FDv2Config Build() const; | ||
|
|
||
| private: | ||
| FDv2Builder(); | ||
|
|
||
| built::FDv2Config config_; | ||
| }; | ||
|
|
||
| } // namespace launchdarkly::server_side::config::builders | ||
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
56 changes: 56 additions & 0 deletions
56
libs/server-sdk/include/launchdarkly/server_side/config/built/data_system/fdv2_config.hpp
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| #pragma once | ||
|
|
||
| #include <launchdarkly/config/shared/built/data_source_config.hpp> | ||
| #include <launchdarkly/config/shared/sdks.hpp> | ||
|
|
||
| #include <chrono> | ||
| #include <optional> | ||
| #include <string> | ||
| #include <variant> | ||
| #include <vector> | ||
|
|
||
| namespace launchdarkly::server_side::config::built { | ||
|
|
||
| struct FDv2Config { | ||
| struct StreamingConfig { | ||
| std::chrono::milliseconds initial_reconnect_delay; | ||
| std::optional<std::string> filter_key; | ||
| std::optional<std::string> base_url_override; | ||
|
|
||
| friend bool operator==(StreamingConfig const& lhs, | ||
| StreamingConfig const& rhs) { | ||
| return lhs.initial_reconnect_delay == rhs.initial_reconnect_delay && | ||
| lhs.filter_key == rhs.filter_key && | ||
| lhs.base_url_override == rhs.base_url_override; | ||
| } | ||
| }; | ||
|
|
||
| struct PollingConfig { | ||
| std::chrono::seconds poll_interval; | ||
| std::optional<std::string> filter_key; | ||
| std::optional<std::string> base_url_override; | ||
|
|
||
| friend bool operator==(PollingConfig const& lhs, | ||
| PollingConfig const& rhs) { | ||
| return lhs.poll_interval == rhs.poll_interval && | ||
| lhs.filter_key == rhs.filter_key && | ||
| lhs.base_url_override == rhs.base_url_override; | ||
| } | ||
| }; | ||
|
|
||
| using FDv1StreamingConfig = | ||
| launchdarkly::config::shared::built::StreamingConfig< | ||
| launchdarkly::config::shared::ServerSDK>; | ||
| using FDv1PollingConfig = | ||
| launchdarkly::config::shared::built::PollingConfig< | ||
| launchdarkly::config::shared::ServerSDK>; | ||
|
|
||
| std::vector<PollingConfig> initializers; | ||
| std::vector<std::variant<StreamingConfig, PollingConfig>> synchronizers; | ||
| std::optional<std::variant<FDv1StreamingConfig, FDv1PollingConfig>> | ||
| fdv1_fallback; | ||
| std::chrono::milliseconds fallback_timeout; | ||
| std::chrono::milliseconds recovery_timeout; | ||
| }; | ||
|
|
||
| } // namespace launchdarkly::server_side::config::built |
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The FDv2 endpoints don't support filters as far as I am aware. Instead we are depending on view keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I'm misunderstanding. Isn't that what these are?
https://github.com/launchdarkly/java-core/blob/ad2ac08c571ef067f3df79a2c0774229c722cc90/lib/sdk/server/src/main/java/com/launchdarkly/sdk/server/StreamingSynchronizerImpl.java#L124-L127
https://github.com/launchdarkly/java-core/blob/ad2ac08c571ef067f3df79a2c0774229c722cc90/lib/sdk/server/src/main/java/com/launchdarkly/sdk/server/integrations/FDv2StreamingSynchronizerBuilder.java#L81