Skip to content

Commit 38e192b

Browse files
committed
Merge remote-tracking branch 'origin/main' into beeklimt/SDK-2551
2 parents 34b3a6c + 43850ce commit 38e192b

24 files changed

Lines changed: 977 additions & 135 deletions

libs/server-sdk/include/launchdarkly/server_side/config/builders/data_system/data_system_builder.hpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <launchdarkly/server_side/config/builders/data_system/background_sync_builder.hpp>
4+
#include <launchdarkly/server_side/config/builders/data_system/fdv2_builder.hpp>
45
#include <launchdarkly/server_side/config/builders/data_system/lazy_load_builder.hpp>
56
#include <launchdarkly/server_side/config/built/data_system/data_system_config.hpp>
67

@@ -13,6 +14,7 @@ class DataSystemBuilder {
1314
DataSystemBuilder();
1415
using BackgroundSync = BackgroundSyncBuilder;
1516
using LazyLoad = LazyLoadBuilder;
17+
using FDv2 = FDv2Builder;
1618

1719
/**
1820
* @brief Alias for Enabled(false).
@@ -46,10 +48,19 @@ class DataSystemBuilder {
4648
*/
4749
DataSystemBuilder& Method(LazyLoad lazy_load);
4850

51+
/**
52+
* @brief Configures the FDv2 data system, which receives flag delivery
53+
* updates over the new changeset-based protocol with built-in fallback
54+
* and recovery semantics.
55+
* @param fdv2 FDv2 configuration.
56+
* @return Reference to this.
57+
*/
58+
DataSystemBuilder& Method(FDv2 fdv2);
59+
4960
[[nodiscard]] tl::expected<built::DataSystemConfig, Error> Build() const;
5061

5162
private:
52-
std::optional<std::variant<BackgroundSync, LazyLoad>> method_builder_;
63+
std::optional<std::variant<BackgroundSync, LazyLoad, FDv2>> method_builder_;
5364
built::DataSystemConfig config_;
5465
};
5566

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
#pragma once
2+
3+
#include <launchdarkly/config/shared/builders/data_source_builder.hpp>
4+
#include <launchdarkly/config/shared/sdks.hpp>
5+
#include <launchdarkly/server_side/config/built/data_system/fdv2_config.hpp>
6+
7+
#include <chrono>
8+
#include <optional>
9+
#include <string>
10+
11+
namespace launchdarkly::server_side::config::builders {
12+
13+
class FDv2Builder {
14+
public:
15+
class Streaming {
16+
public:
17+
Streaming& InitialReconnectDelay(std::chrono::milliseconds delay);
18+
Streaming& BaseUrl(std::string base_url);
19+
[[nodiscard]] built::FDv2Config::StreamingConfig Build() const;
20+
21+
private:
22+
std::chrono::milliseconds initial_reconnect_delay_{1000};
23+
std::optional<std::string> filter_key_;
24+
std::optional<std::string> base_url_override_;
25+
};
26+
27+
class Polling {
28+
public:
29+
Polling& PollInterval(std::chrono::seconds interval);
30+
Polling& BaseUrl(std::string base_url);
31+
[[nodiscard]] built::FDv2Config::PollingConfig Build() const;
32+
33+
private:
34+
std::chrono::seconds poll_interval_{30};
35+
std::optional<std::string> filter_key_;
36+
std::optional<std::string> base_url_override_;
37+
};
38+
39+
/**
40+
* @return A builder pre-populated with the spec-recommended initializers,
41+
* synchronizers, and FDv1 fallback. Equivalent to calling
42+
* Initializer(), Synchronizer(), and FDv1Fallback() with the
43+
* standard sources.
44+
*/
45+
static FDv2Builder Default();
46+
47+
/**
48+
* @return A builder with no initializers, no synchronizers, and no
49+
* FDv1 fallback. Callers must add sources explicitly.
50+
*/
51+
static FDv2Builder Custom();
52+
53+
/**
54+
* @brief Appends a polling initializer to the initializers list.
55+
* @param source Polling source configuration for the initializer.
56+
* @return Reference to this.
57+
*/
58+
FDv2Builder& Initializer(Polling source);
59+
60+
/**
61+
* @brief Appends a streaming synchronizer to the synchronizers list.
62+
* Order in the list determines preference: the first entry is the
63+
* primary synchronizer, subsequent entries are fallbacks.
64+
* @param source Streaming source configuration.
65+
* @return Reference to this.
66+
*/
67+
FDv2Builder& Synchronizer(Streaming source);
68+
69+
/**
70+
* @brief Appends a polling synchronizer to the synchronizers list. See
71+
* Synchronizer(Streaming) for ordering semantics.
72+
* @param source Polling source configuration.
73+
* @return Reference to this.
74+
*/
75+
FDv2Builder& Synchronizer(Polling source);
76+
77+
using FDv1Streaming =
78+
launchdarkly::config::shared::builders::StreamingBuilder<
79+
launchdarkly::config::shared::ServerSDK>;
80+
using FDv1Polling = launchdarkly::config::shared::builders::PollingBuilder<
81+
launchdarkly::config::shared::ServerSDK>;
82+
83+
/**
84+
* @brief Configures the FDv1 streaming source used as a last-resort
85+
* fallback when the LaunchDarkly service signals (via the
86+
* X-LD-FD-Fallback header) that the SDK should switch to FDv1. The
87+
* fallback reads its endpoint from the top-level ServiceEndpoints; to
88+
* point the fallback at a custom URL, configure ServiceEndpoints
89+
* accordingly.
90+
* @param source FDv1 streaming source configuration.
91+
* @return Reference to this.
92+
*/
93+
FDv2Builder& FDv1Fallback(FDv1Streaming source);
94+
95+
/**
96+
* @brief Configures the FDv1 polling source used as a last-resort
97+
* fallback when the LaunchDarkly service signals (via the
98+
* X-LD-FD-Fallback header) that the SDK should switch to FDv1. The
99+
* fallback reads its endpoint from the top-level ServiceEndpoints; to
100+
* point the fallback at a custom URL, configure ServiceEndpoints
101+
* accordingly.
102+
* @param source FDv1 polling source configuration.
103+
* @return Reference to this.
104+
*/
105+
FDv2Builder& FDv1Fallback(FDv1Polling source);
106+
107+
/**
108+
* @brief Disables the FDv1 fallback. After this call, an FDv1
109+
* fallback directive from the service leaves the data source in
110+
* the interrupted state and schedules an FDv2 retry on the
111+
* directive's TTL.
112+
* @return Reference to this.
113+
*/
114+
FDv2Builder& DisableFDv1Fallback();
115+
116+
/**
117+
* @brief Sets how long the active synchronizer may remain interrupted
118+
* before the orchestrator falls back to the next-preferred synchronizer.
119+
* @param timeout Duration the synchronizer must be continuously
120+
* interrupted for before fallback fires.
121+
* @return Reference to this.
122+
*/
123+
FDv2Builder& FallbackTimeout(std::chrono::milliseconds timeout);
124+
125+
/**
126+
* @brief Sets how long a fallback synchronizer must run successfully
127+
* before the orchestrator attempts to recover to the primary
128+
* synchronizer.
129+
* @param timeout Duration the fallback synchronizer must run before a
130+
* recovery attempt is made.
131+
* @return Reference to this.
132+
*/
133+
FDv2Builder& RecoveryTimeout(std::chrono::milliseconds timeout);
134+
135+
[[nodiscard]] built::FDv2Config Build() const;
136+
137+
private:
138+
FDv2Builder();
139+
140+
built::FDv2Config config_;
141+
};
142+
143+
} // namespace launchdarkly::server_side::config::builders
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22

33
#include <launchdarkly/server_side/config/built/data_system/background_sync_config.hpp>
4+
#include <launchdarkly/server_side/config/built/data_system/fdv2_config.hpp>
45
#include <launchdarkly/server_side/config/built/data_system/lazy_load_config.hpp>
56

67
#include <variant>
@@ -9,7 +10,7 @@ namespace launchdarkly::server_side::config::built {
910

1011
struct DataSystemConfig {
1112
bool disabled;
12-
std::variant<LazyLoadConfig, BackgroundSyncConfig> system_;
13+
std::variant<LazyLoadConfig, BackgroundSyncConfig, FDv2Config> system_;
1314
};
1415

1516
} // namespace launchdarkly::server_side::config::built
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#pragma once
2+
3+
#include <launchdarkly/config/shared/built/data_source_config.hpp>
4+
#include <launchdarkly/config/shared/sdks.hpp>
5+
6+
#include <chrono>
7+
#include <optional>
8+
#include <string>
9+
#include <variant>
10+
#include <vector>
11+
12+
namespace launchdarkly::server_side::config::built {
13+
14+
struct FDv2Config {
15+
struct StreamingConfig {
16+
std::chrono::milliseconds initial_reconnect_delay;
17+
std::optional<std::string> base_url_override;
18+
19+
friend bool operator==(StreamingConfig const& lhs,
20+
StreamingConfig const& rhs) {
21+
return lhs.initial_reconnect_delay == rhs.initial_reconnect_delay &&
22+
lhs.base_url_override == rhs.base_url_override;
23+
}
24+
};
25+
26+
struct PollingConfig {
27+
std::chrono::seconds poll_interval;
28+
std::optional<std::string> base_url_override;
29+
30+
friend bool operator==(PollingConfig const& lhs,
31+
PollingConfig const& rhs) {
32+
return lhs.poll_interval == rhs.poll_interval &&
33+
lhs.base_url_override == rhs.base_url_override;
34+
}
35+
};
36+
37+
using FDv1StreamingConfig =
38+
launchdarkly::config::shared::built::StreamingConfig<
39+
launchdarkly::config::shared::ServerSDK>;
40+
using FDv1PollingConfig =
41+
launchdarkly::config::shared::built::PollingConfig<
42+
launchdarkly::config::shared::ServerSDK>;
43+
44+
std::vector<PollingConfig> initializers;
45+
std::vector<std::variant<StreamingConfig, PollingConfig>> synchronizers;
46+
std::optional<std::variant<FDv1StreamingConfig, FDv1PollingConfig>>
47+
fdv1_fallback;
48+
std::chrono::milliseconds fallback_timeout;
49+
std::chrono::milliseconds recovery_timeout;
50+
};
51+
52+
} // namespace launchdarkly::server_side::config::built

libs/server-sdk/src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ target_sources(${LIBNAME}
3030
config/builders/data_system/background_sync_builder.cpp
3131
config/builders/data_system/bootstrap_builder.cpp
3232
config/builders/data_system/data_system_builder.cpp
33+
config/builders/data_system/fdv2_builder.cpp
3334
config/builders/data_system/lazy_load_builder.cpp
3435
config/builders/data_system/data_destination_builder.cpp
3536
config/builders/big_segments_builder.cpp
@@ -81,6 +82,10 @@ target_sources(${LIBNAME}
8182
data_systems/fdv2/fdv2_data_system.cpp
8283
data_systems/fdv2/fdv1_adapter_synchronizer.hpp
8384
data_systems/fdv2/fdv1_adapter_synchronizer.cpp
85+
data_systems/fdv2/synchronizer_factories.hpp
86+
data_systems/fdv2/synchronizer_factories.cpp
87+
data_systems/fdv2/initializer_factories.hpp
88+
data_systems/fdv2/initializer_factories.cpp
8489
data_systems/background_sync/sources/streaming/streaming_data_source.hpp
8590
data_systems/background_sync/sources/streaming/streaming_data_source.cpp
8691
data_systems/background_sync/sources/streaming/event_handler.hpp

0 commit comments

Comments
 (0)