Skip to content

Commit 6287dc1

Browse files
committed
feat: Add C bindings for FDv2 data system
1 parent 3459bbb commit 6287dc1

6 files changed

Lines changed: 618 additions & 1 deletion

File tree

libs/server-sdk/include/launchdarkly/server_side/bindings/c/config/builder.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#pragma once
55

66
#include <launchdarkly/server_side/bindings/c/config/config.h>
7+
#include <launchdarkly/server_side/bindings/c/config/fdv2_builder/fdv2_builder.h>
78
#include <launchdarkly/server_side/bindings/c/config/lazy_load_builder/lazy_load_builder.h>
89
#include <launchdarkly/server_side/bindings/c/hook.h>
910

@@ -256,6 +257,27 @@ LDServerConfigBuilder_DataSystem_LazyLoad(
256257
LDServerConfigBuilder b,
257258
LDServerLazyLoadBuilder lazy_load_builder);
258259

260+
/**
261+
* Configures the FDv2 data system. The builder is automatically consumed.
262+
*
263+
* This method is mutually exclusive with the BackgroundSync_Streaming,
264+
* BackgroundSync_Polling, and LazyLoad builders.
265+
*
266+
* WARNING: Do not call any other LDServerFDv2Builder function on the provided
267+
* builder after calling this function. It is undefined behavior.
268+
*
269+
* FDv2 receives flag delivery updates over the changeset-based protocol with
270+
* built-in fallback and recovery semantics. An optional FDv1 fallback may be
271+
* configured on the FDv2 builder for service-directed protocol fallback.
272+
*
273+
* @param b Server config builder. Must not be NULL.
274+
* @param fdv2_builder The FDv2 builder. The builder is consumed; do not free
275+
* it. Must not be NULL.
276+
*/
277+
LD_EXPORT(void)
278+
LDServerConfigBuilder_DataSystem_FDv2(LDServerConfigBuilder b,
279+
LDServerFDv2Builder fdv2_builder);
280+
259281
/**
260282
* Specify if the SDK's data system should be enabled or not.
261283
*
Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
/** @file fdv2_builder.h */
2+
// NOLINTBEGIN modernize-use-using
3+
4+
#pragma once
5+
6+
#include <launchdarkly/bindings/c/export.h>
7+
8+
#include <stdbool.h>
9+
10+
#ifdef __cplusplus
11+
extern "C" { // only need to export C interface if used by C++ source code
12+
#endif
13+
14+
typedef struct _LDServerFDv2Builder* LDServerFDv2Builder;
15+
typedef struct _LDServerFDv2StreamingBuilder* LDServerFDv2StreamingBuilder;
16+
typedef struct _LDServerFDv2PollingBuilder* LDServerFDv2PollingBuilder;
17+
18+
/* Reused as the input handles for LDServerFDv2Builder_FDv1Fallback_*. Fully
19+
* declared in <launchdarkly/server_side/bindings/c/config/builder.h>. */
20+
typedef struct _LDServerDataSourceStreamBuilder* LDServerDataSourceStreamBuilder;
21+
typedef struct _LDServerDataSourcePollBuilder* LDServerDataSourcePollBuilder;
22+
23+
/**
24+
* Creates an FDv2 builder pre-populated with the spec-recommended initializers,
25+
* synchronizers, and FDv1 fallback. Suitable for most applications without
26+
* further configuration.
27+
*
28+
* If not passed into the config builder, must be manually freed with
29+
* LDServerFDv2Builder_Free.
30+
*
31+
* @return A new FDv2 builder with default sources.
32+
*/
33+
LD_EXPORT(LDServerFDv2Builder)
34+
LDServerFDv2Builder_Default(void);
35+
36+
/**
37+
* Creates an FDv2 builder with no initializers, no synchronizers, and no
38+
* FDv1 fallback. Sources must be added explicitly via Initializer_*,
39+
* Synchronizer_*, and FDv1Fallback_* methods.
40+
*
41+
* If not passed into the config builder, must be manually freed with
42+
* LDServerFDv2Builder_Free.
43+
*
44+
* @return A new empty FDv2 builder.
45+
*/
46+
LD_EXPORT(LDServerFDv2Builder)
47+
LDServerFDv2Builder_Custom(void);
48+
49+
/**
50+
* Frees an FDv2 builder. Do not call if the builder was consumed by the
51+
* config builder.
52+
*
53+
* @param b Builder to free.
54+
*/
55+
LD_EXPORT(void)
56+
LDServerFDv2Builder_Free(LDServerFDv2Builder b);
57+
58+
/**
59+
* Creates a new FDv2 Streaming source builder.
60+
*
61+
* If not passed into an FDv2 builder, must be manually freed with
62+
* LDServerFDv2StreamingBuilder_Free.
63+
*
64+
* @return A new FDv2 Streaming source builder.
65+
*/
66+
LD_EXPORT(LDServerFDv2StreamingBuilder)
67+
LDServerFDv2StreamingBuilder_New(void);
68+
69+
/**
70+
* Sets the initial reconnect delay for the FDv2 streaming connection.
71+
*
72+
* The streaming service uses a backoff algorithm (with jitter) every time
73+
* the connection needs to be reestablished. The delay for the first
74+
* reconnection will start near this value, and then increase exponentially
75+
* for any subsequent connection failures.
76+
*
77+
* @param b FDv2 Streaming source builder. Must not be NULL.
78+
* @param milliseconds Initial delay for a reconnection attempt.
79+
*/
80+
LD_EXPORT(void)
81+
LDServerFDv2StreamingBuilder_InitialReconnectDelayMs(
82+
LDServerFDv2StreamingBuilder b,
83+
unsigned int milliseconds);
84+
85+
/**
86+
* Overrides the base URL used by this FDv2 streaming source. By default the
87+
* streaming source reads its endpoint from the top-level ServiceEndpoints
88+
* configuration; this override takes precedence for this source only.
89+
*
90+
* @param b FDv2 Streaming source builder. Must not be NULL.
91+
* @param base_url Target URL. Must not be NULL.
92+
*/
93+
LD_EXPORT(void)
94+
LDServerFDv2StreamingBuilder_BaseUrl(LDServerFDv2StreamingBuilder b,
95+
char const* base_url);
96+
97+
/**
98+
* Frees an FDv2 Streaming source builder. Do not call if the builder was
99+
* consumed by an FDv2 builder.
100+
*
101+
* @param b Builder to free.
102+
*/
103+
LD_EXPORT(void)
104+
LDServerFDv2StreamingBuilder_Free(LDServerFDv2StreamingBuilder b);
105+
106+
/**
107+
* Creates a new FDv2 Polling source builder.
108+
*
109+
* If not passed into an FDv2 builder, must be manually freed with
110+
* LDServerFDv2PollingBuilder_Free.
111+
*
112+
* @return A new FDv2 Polling source builder.
113+
*/
114+
LD_EXPORT(LDServerFDv2PollingBuilder)
115+
LDServerFDv2PollingBuilder_New(void);
116+
117+
/**
118+
* Sets the interval at which this FDv2 polling source will poll for flag
119+
* updates.
120+
*
121+
* @param b FDv2 Polling source builder. Must not be NULL.
122+
* @param seconds Polling interval in seconds.
123+
*/
124+
LD_EXPORT(void)
125+
LDServerFDv2PollingBuilder_PollIntervalS(LDServerFDv2PollingBuilder b,
126+
unsigned int seconds);
127+
128+
/**
129+
* Overrides the base URL used by this FDv2 polling source. By default the
130+
* polling source reads its endpoint from the top-level ServiceEndpoints
131+
* configuration; this override takes precedence for this source only.
132+
*
133+
* @param b FDv2 Polling source builder. Must not be NULL.
134+
* @param base_url Target URL. Must not be NULL.
135+
*/
136+
LD_EXPORT(void)
137+
LDServerFDv2PollingBuilder_BaseUrl(LDServerFDv2PollingBuilder b,
138+
char const* base_url);
139+
140+
/**
141+
* Frees an FDv2 Polling source builder. Do not call if the builder was
142+
* consumed by an FDv2 builder.
143+
*
144+
* @param b Builder to free.
145+
*/
146+
LD_EXPORT(void)
147+
LDServerFDv2PollingBuilder_Free(LDServerFDv2PollingBuilder b);
148+
149+
/**
150+
* Appends an FDv2 polling initializer to the FDv2 builder's initializers
151+
* list. The source builder is automatically freed.
152+
*
153+
* WARNING: Do not call any other LDServerFDv2PollingBuilder function on the
154+
* provided builder after calling this function. It is undefined behavior.
155+
*
156+
* @param b FDv2 builder. Must not be NULL.
157+
* @param polling The FDv2 Polling source builder. The builder is consumed;
158+
* do not free it. Must not be NULL.
159+
*/
160+
LD_EXPORT(void)
161+
LDServerFDv2Builder_Initializer_Polling(LDServerFDv2Builder b,
162+
LDServerFDv2PollingBuilder polling);
163+
164+
/**
165+
* Appends an FDv2 streaming synchronizer to the FDv2 builder's synchronizers
166+
* list. The source builder is automatically freed.
167+
*
168+
* Order in the list determines preference: the first entry is the primary
169+
* synchronizer, subsequent entries are fallbacks.
170+
*
171+
* WARNING: Do not call any other LDServerFDv2StreamingBuilder function on
172+
* the provided builder after calling this function. It is undefined behavior.
173+
*
174+
* @param b FDv2 builder. Must not be NULL.
175+
* @param streaming The FDv2 Streaming source builder. The builder is
176+
* consumed; do not free it. Must not be NULL.
177+
*/
178+
LD_EXPORT(void)
179+
LDServerFDv2Builder_Synchronizer_Streaming(
180+
LDServerFDv2Builder b,
181+
LDServerFDv2StreamingBuilder streaming);
182+
183+
/**
184+
* Appends an FDv2 polling synchronizer to the FDv2 builder's synchronizers
185+
* list. The source builder is automatically freed.
186+
*
187+
* See LDServerFDv2Builder_Synchronizer_Streaming for ordering semantics.
188+
*
189+
* WARNING: Do not call any other LDServerFDv2PollingBuilder function on the
190+
* provided builder after calling this function. It is undefined behavior.
191+
*
192+
* @param b FDv2 builder. Must not be NULL.
193+
* @param polling The FDv2 Polling source builder. The builder is consumed;
194+
* do not free it. Must not be NULL.
195+
*/
196+
LD_EXPORT(void)
197+
LDServerFDv2Builder_Synchronizer_Polling(LDServerFDv2Builder b,
198+
LDServerFDv2PollingBuilder polling);
199+
200+
/**
201+
* Configures the FDv1 streaming source used as a last-resort fallback when
202+
* the LaunchDarkly service signals (via the X-LD-FD-Fallback header) that
203+
* the SDK should switch to FDv1. The fallback reads its endpoint from the
204+
* top-level ServiceEndpoints configuration. The source builder is
205+
* automatically freed.
206+
*
207+
* The fdv1_streaming parameter uses the same handle type as the
208+
* BackgroundSync streaming synchronizer
209+
* (LDServerDataSourceStreamBuilder_New); the underlying C++ type is shared.
210+
*
211+
* WARNING: Do not call any other LDServerDataSourceStreamBuilder function
212+
* on the provided builder after calling this function. It is undefined
213+
* behavior.
214+
*
215+
* @param b FDv2 builder. Must not be NULL.
216+
* @param fdv1_streaming The FDv1 Streaming source builder. The builder is
217+
* consumed; do not free it. Must not be NULL.
218+
*/
219+
LD_EXPORT(void)
220+
LDServerFDv2Builder_FDv1Fallback_Streaming(
221+
LDServerFDv2Builder b,
222+
LDServerDataSourceStreamBuilder fdv1_streaming);
223+
224+
/**
225+
* Configures the FDv1 polling source used as a last-resort fallback when
226+
* the LaunchDarkly service signals (via the X-LD-FD-Fallback header) that
227+
* the SDK should switch to FDv1. The fallback reads its endpoint from the
228+
* top-level ServiceEndpoints configuration. The source builder is
229+
* automatically freed.
230+
*
231+
* The fdv1_polling parameter uses the same handle type as the BackgroundSync
232+
* polling synchronizer (LDServerDataSourcePollBuilder_New); the underlying
233+
* C++ type is shared.
234+
*
235+
* WARNING: Do not call any other LDServerDataSourcePollBuilder function on
236+
* the provided builder after calling this function. It is undefined behavior.
237+
*
238+
* @param b FDv2 builder. Must not be NULL.
239+
* @param fdv1_polling The FDv1 Polling source builder. The builder is
240+
* consumed; do not free it. Must not be NULL.
241+
*/
242+
LD_EXPORT(void)
243+
LDServerFDv2Builder_FDv1Fallback_Polling(
244+
LDServerFDv2Builder b,
245+
LDServerDataSourcePollBuilder fdv1_polling);
246+
247+
/**
248+
* Disables the FDv1 fallback. After this call, an FDv1 fallback directive
249+
* from the service leaves the data source in the interrupted state and
250+
* schedules an FDv2 retry on the directive's TTL.
251+
*
252+
* @param b FDv2 builder. Must not be NULL.
253+
*/
254+
LD_EXPORT(void)
255+
LDServerFDv2Builder_DisableFDv1Fallback(LDServerFDv2Builder b);
256+
257+
/**
258+
* Sets how long the active synchronizer may remain interrupted before the
259+
* orchestrator falls back to the next-preferred synchronizer.
260+
*
261+
* @param b FDv2 builder. Must not be NULL.
262+
* @param milliseconds Duration the synchronizer must be continuously
263+
* interrupted for before fallback fires.
264+
*/
265+
LD_EXPORT(void)
266+
LDServerFDv2Builder_FallbackTimeoutMs(LDServerFDv2Builder b,
267+
unsigned int milliseconds);
268+
269+
/**
270+
* Sets how long a fallback synchronizer must run successfully before the
271+
* orchestrator attempts to recover to the primary synchronizer.
272+
*
273+
* @param b FDv2 builder. Must not be NULL.
274+
* @param milliseconds Duration the fallback synchronizer must run before a
275+
* recovery attempt is made.
276+
*/
277+
LD_EXPORT(void)
278+
LDServerFDv2Builder_RecoveryTimeoutMs(LDServerFDv2Builder b,
279+
unsigned int milliseconds);
280+
281+
#ifdef __cplusplus
282+
}
283+
#endif
284+
285+
// NOLINTEND modernize-use-using

libs/server-sdk/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ target_sources(${LIBNAME}
111111
hooks/hook_executor.cpp
112112
bindings/c/sdk.cpp
113113
bindings/c/builder.cpp
114+
bindings/c/fdv2_builder.cpp
114115
bindings/c/config.cpp
115116
bindings/c/all_flags_state/all_flags_state.cpp
116117
bindings/c/hook.cpp

libs/server-sdk/src/bindings/c/builder.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,17 @@ LDServerConfigBuilder_DataSystem_LazyLoad(
225225
LDServerLazyLoadBuilder_Free(lazy_load_builder);
226226
}
227227

228+
LD_EXPORT(void)
229+
LDServerConfigBuilder_DataSystem_FDv2(LDServerConfigBuilder b,
230+
LDServerFDv2Builder fdv2_builder) {
231+
LD_ASSERT_NOT_NULL(b);
232+
LD_ASSERT_NOT_NULL(fdv2_builder);
233+
234+
auto* fb = reinterpret_cast<DataSystemBuilder::FDv2*>(fdv2_builder);
235+
TO_BUILDER(b)->DataSystem().Method(*fb);
236+
LDServerFDv2Builder_Free(fdv2_builder);
237+
}
238+
228239
LD_EXPORT(void)
229240
LDServerConfigBuilder_DataSystem_Enabled(LDServerConfigBuilder b,
230241
bool const enabled) {

0 commit comments

Comments
 (0)