-
Notifications
You must be signed in to change notification settings - Fork 4
refactor: define new Synchronizer and Initializer interfaces for FDv2 #517
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
Merged
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
bf945b3
refactor: add Apply method to MemoryStore for transactional change sets
beekld cc59635
fix an unneeded copy, and warn on missing enum case
beekld 82d09d2
add an ApplyResult with the changed keys
beekld 259d8e9
mark the apply result as nodiscard for now
beekld f5b82bf
simplify tests
beekld 7826357
simplify, since FDv2 doesnt require version checking in memory store
beekld 651a780
refactor: define new Synchronizer and Initializer interfaces for FDv2
beekld fe37f55
move selector source into Next
beekld c470763
Merge branch 'main' into beeklimt/SDK-2096
beekld ed22857
distinguish between timeouts and errors
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,6 +42,7 @@ build-dynamic | |
| build-static-debug | ||
| build-dynamic-debug | ||
| cmake-build-* | ||
| .cache | ||
|
|
||
| # For Macs.. | ||
| .DS_Store | ||
|
|
||
70 changes: 70 additions & 0 deletions
70
libs/server-sdk/src/data_interfaces/source/fdv2_source_result.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,70 @@ | ||
| #pragma once | ||
|
|
||
| #include <launchdarkly/data_model/fdv2_change.hpp> | ||
| #include <launchdarkly/data_sources/data_source_status_error_info.hpp> | ||
|
|
||
| #include <optional> | ||
| #include <string> | ||
| #include <variant> | ||
|
|
||
| namespace launchdarkly::server_side::data_interfaces { | ||
|
|
||
| /** | ||
| * Result returned by IFDv2Initializer::Run and IFDv2Synchronizer::Next. | ||
| * | ||
| * Mirrors Java's FDv2SourceResult. | ||
| */ | ||
| struct FDv2SourceResult { | ||
| using ErrorInfo = common::data_sources::DataSourceStatusErrorInfo; | ||
|
|
||
| /** | ||
| * A changeset was successfully received and is ready to apply. | ||
| */ | ||
| struct ChangeSet { | ||
| data_model::FDv2ChangeSet change_set; | ||
| /** If true, the server signaled that the client should fall back to | ||
| * FDv1. */ | ||
| bool fdv1_fallback; | ||
| }; | ||
|
|
||
| /** | ||
| * A transient error occurred; the source may recover. | ||
| */ | ||
| struct Interrupted { | ||
| ErrorInfo error; | ||
| bool fdv1_fallback; | ||
| }; | ||
|
|
||
| /** | ||
| * A non-recoverable error occurred; the source should not be retried. | ||
| */ | ||
| struct TerminalError { | ||
| ErrorInfo error; | ||
| bool fdv1_fallback; | ||
| }; | ||
|
|
||
| /** | ||
| * The source was closed cleanly (via Close()). | ||
| */ | ||
| struct Shutdown {}; | ||
|
|
||
| /** | ||
| * The server sent a goodbye; the orchestrator should rotate sources. | ||
| */ | ||
| struct Goodbye { | ||
| std::optional<std::string> reason; | ||
| bool fdv1_fallback; | ||
| }; | ||
|
|
||
| /** | ||
| * Next() returned because the timeout expired before a result arrived. | ||
| */ | ||
| struct Timeout {}; | ||
|
|
||
| using Value = std::variant<ChangeSet, Interrupted, TerminalError, Shutdown, | ||
| Goodbye, Timeout>; | ||
|
|
||
| Value value; | ||
| }; | ||
|
|
||
| } // namespace launchdarkly::server_side::data_interfaces | ||
46 changes: 46 additions & 0 deletions
46
libs/server-sdk/src/data_interfaces/source/ifdv2_initializer.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,46 @@ | ||
| #pragma once | ||
|
|
||
| #include "fdv2_source_result.hpp" | ||
|
|
||
| #include <string> | ||
|
|
||
| namespace launchdarkly::server_side::data_interfaces { | ||
|
|
||
| /** | ||
| * Defines a one-shot data source that runs to completion and returns a single | ||
| * result. Used during the initialization phase of FDv2, before handing off to | ||
| * an IFDv2Synchronizer. | ||
| */ | ||
| class IFDv2Initializer { | ||
| public: | ||
| /** | ||
| * Run the initializer to completion. Blocks until a result is available. | ||
| * Called at most once per instance. | ||
| * | ||
| * Close() may be called from another thread to unblock Run(), in which | ||
| * case Run() returns FDv2SourceResult::Shutdown. | ||
| */ | ||
| virtual FDv2SourceResult Run() = 0; | ||
|
|
||
| /** | ||
| * Unblocks any in-progress Run() call, causing it to return | ||
| * FDv2SourceResult::Shutdown. | ||
| */ | ||
| virtual void Close() = 0; | ||
|
|
||
| /** | ||
| * @return A display-suitable name of the initializer. | ||
| */ | ||
| [[nodiscard]] virtual std::string const& Identity() const = 0; | ||
|
|
||
| virtual ~IFDv2Initializer() = default; | ||
| IFDv2Initializer(IFDv2Initializer const&) = delete; | ||
| IFDv2Initializer(IFDv2Initializer&&) = delete; | ||
| IFDv2Initializer& operator=(IFDv2Initializer const&) = delete; | ||
| IFDv2Initializer& operator=(IFDv2Initializer&&) = delete; | ||
|
|
||
| protected: | ||
| IFDv2Initializer() = default; | ||
| }; | ||
|
|
||
| } // namespace launchdarkly::server_side::data_interfaces |
62 changes: 62 additions & 0 deletions
62
libs/server-sdk/src/data_interfaces/source/ifdv2_synchronizer.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,62 @@ | ||
| #pragma once | ||
|
|
||
| #include "fdv2_source_result.hpp" | ||
|
|
||
| #include <launchdarkly/data_model/selector.hpp> | ||
|
|
||
| #include <chrono> | ||
| #include <string> | ||
|
|
||
| namespace launchdarkly::server_side::data_interfaces { | ||
|
|
||
| /** | ||
| * Defines a continuous data source that produces a stream of results. Used | ||
| * during the synchronization phase of FDv2, after initialization is complete. | ||
| * | ||
| * The stream is started lazily on the first call to Next(). The synchronizer | ||
| * runs until Close() is called. | ||
| */ | ||
| class IFDv2Synchronizer { | ||
| public: | ||
| /** | ||
| * Block until the next result is available or the timeout expires. | ||
| * | ||
| * On the first call, the synchronizer starts its underlying connection. | ||
| * Subsequent calls continue reading from the same connection. | ||
| * | ||
| * If the timeout expires before a result arrives, returns | ||
| * FDv2SourceResult::Timeout. The orchestrator uses this to evaluate | ||
| * fallback conditions. | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * | ||
| * Close() may be called from another thread to unblock Next(), in which | ||
| * case Next() returns FDv2SourceResult::Shutdown. | ||
| * | ||
| * @param timeout Maximum time to wait for the next result. | ||
| * @param selector The selector to send with the request, reflecting any | ||
| * changesets applied since the previous call. | ||
| */ | ||
| virtual FDv2SourceResult Next(std::chrono::milliseconds timeout, | ||
| data_model::Selector selector) = 0; | ||
|
|
||
| /** | ||
| * Unblocks any in-progress Next() call, causing it to return | ||
| * FDv2SourceResult::Shutdown, and releases underlying resources. | ||
| */ | ||
| virtual void Close() = 0; | ||
|
|
||
| /** | ||
| * @return A display-suitable name of the synchronizer. | ||
| */ | ||
| [[nodiscard]] virtual std::string const& Identity() const = 0; | ||
|
|
||
| virtual ~IFDv2Synchronizer() = default; | ||
| IFDv2Synchronizer(IFDv2Synchronizer const&) = delete; | ||
| IFDv2Synchronizer(IFDv2Synchronizer&&) = delete; | ||
| IFDv2Synchronizer& operator=(IFDv2Synchronizer const&) = delete; | ||
| IFDv2Synchronizer& operator=(IFDv2Synchronizer&&) = delete; | ||
|
|
||
| protected: | ||
| IFDv2Synchronizer() = default; | ||
| }; | ||
|
|
||
| } // namespace launchdarkly::server_side::data_interfaces | ||
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.
This is nicer than the Java shenanigans.