Skip to content

Commit f916106

Browse files
authored
Merge branch 'main' into rlamb/basic-network-request-abstraction
2 parents 75c79b8 + 03e2a59 commit f916106

32 files changed

Lines changed: 5231 additions & 34 deletions

cmake/redis-plus-plus.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ FetchContent_Declare(redis-plus-plus
2525
GIT_REPOSITORY https://github.com/sewenew/redis-plus-plus.git
2626
# Post 1.3.15. Required to support FetchContent post 1.3.7 where it was broken.
2727
GIT_TAG fc67c2ebf929ae2cf3b31d959767233f39c5df6a
28-
GIT_SHALLOW TRUE
28+
GIT_SHALLOW FALSE
2929
)
3030

3131
FetchContent_MakeAvailable(redis-plus-plus)

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <launchdarkly/server_side/bindings/c/config/config.h>
77
#include <launchdarkly/server_side/bindings/c/config/lazy_load_builder/lazy_load_builder.h>
8+
#include <launchdarkly/server_side/bindings/c/hook.h>
89

910
#include <launchdarkly/bindings/c/config/logging_builder.h>
1011
#include <launchdarkly/bindings/c/export.h>
@@ -541,6 +542,25 @@ LD_EXPORT(void)
541542
LDServerConfigBuilder_Logging_Custom(LDServerConfigBuilder b,
542543
LDLoggingCustomBuilder custom_builder);
543544

545+
/**
546+
* Registers a hook with the SDK.
547+
*
548+
* Hooks allow you to instrument SDK behavior for logging, analytics,
549+
* or distributed tracing (e.g. OpenTelemetry).
550+
*
551+
* Multiple hooks can be registered. They execute in the order registered.
552+
*
553+
* LIFETIME: The hook struct is copied during this call. The Name string
554+
* must remain valid until LDServerConfigBuilder_Build() is called.
555+
* UserData and function pointers must remain valid for the SDK lifetime.
556+
*
557+
* @param builder Configuration builder. Must not be NULL.
558+
* @param hook Hook to register. The struct is copied. Must not be NULL.
559+
*/
560+
LD_EXPORT(void)
561+
LDServerConfigBuilder_Hooks(LDServerConfigBuilder builder,
562+
struct LDServerSDKHook hook);
563+
544564
/**
545565
* Creates an LDClientConfig. The builder is automatically freed.
546566
*
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/**
2+
* @file evaluation_series_context.h
3+
* @brief C bindings for read-only evaluation context passed to hooks.
4+
*
5+
* EvaluationSeriesContext provides information about a flag evaluation
6+
* to hook callbacks. All data is read-only and valid only during the
7+
* callback execution.
8+
*
9+
* LIFETIME:
10+
* - All context parameters are temporary - valid only during callback
11+
* - Do not store pointers to context data
12+
* - Copy any needed data (strings, values) if you need to retain it
13+
*/
14+
15+
#pragma once
16+
17+
#include <launchdarkly/bindings/c/export.h>
18+
#include <launchdarkly/server_side/bindings/c/hook_context.h>
19+
#include <launchdarkly/bindings/c/value.h>
20+
#include <launchdarkly/bindings/c/context.h>
21+
22+
// No effect in C++, but we want it for C.
23+
// ReSharper disable once CppUnusedIncludeDirective
24+
#include <stdbool.h> // NOLINT(*-deprecated-headers)
25+
26+
#ifdef __cplusplus
27+
extern "C" {
28+
#endif
29+
30+
typedef struct p_LDServerSDKEvaluationSeriesContext* LDServerSDKEvaluationSeriesContext;
31+
32+
/**
33+
* @brief Get the flag key being evaluated.
34+
*
35+
* @param eval_context Evaluation context. Must not be NULL.
36+
* @return Flag key as null-terminated UTF-8 string. Valid only during
37+
* the callback execution. Must not be freed.
38+
*/
39+
LD_EXPORT(char const*)
40+
LDEvaluationSeriesContext_FlagKey(LDServerSDKEvaluationSeriesContext eval_context);
41+
42+
/**
43+
* @brief Get the context (user/organization) being evaluated.
44+
*
45+
* @param eval_context Evaluation context. Must not be NULL.
46+
* @return Context object. Valid only during the callback execution.
47+
* Must not be freed. Do not call LDContext_Free() on this.
48+
*/
49+
LD_EXPORT(LDContext)
50+
LDEvaluationSeriesContext_Context(LDServerSDKEvaluationSeriesContext eval_context);
51+
52+
/**
53+
* @brief Get the default value provided to the variation call.
54+
*
55+
* @param eval_context Evaluation context. Must not be NULL.
56+
* @return Default value. Valid only during the callback execution.
57+
* Must not be freed. Do not call LDValue_Free() on this.
58+
*/
59+
LD_EXPORT(LDValue)
60+
LDEvaluationSeriesContext_DefaultValue(
61+
LDServerSDKEvaluationSeriesContext eval_context);
62+
63+
/**
64+
* @brief Get the name of the variation method called.
65+
*
66+
* Examples: "BoolVariation", "StringVariationDetail", "JsonVariation"
67+
*
68+
* @param eval_context Evaluation context. Must not be NULL.
69+
* @return Method name as null-terminated UTF-8 string. Valid only during
70+
* the callback execution. Must not be freed.
71+
*/
72+
LD_EXPORT(char const*)
73+
LDEvaluationSeriesContext_Method(LDServerSDKEvaluationSeriesContext eval_context);
74+
75+
/**
76+
* @brief Get the hook context provided by the caller.
77+
*
78+
* This contains application-specific data passed to the variation call,
79+
* such as OpenTelemetry span parents.
80+
*
81+
* @param eval_context Evaluation context. Must not be NULL.
82+
* @return Hook context. Valid only during the callback execution.
83+
* Must not be freed. Do not call LDHookContext_Free() on this.
84+
*/
85+
LD_EXPORT(LDHookContext)
86+
LDEvaluationSeriesContext_HookContext(
87+
LDServerSDKEvaluationSeriesContext eval_context);
88+
89+
/**
90+
* @brief Get the environment ID, if available.
91+
*
92+
* The environment ID is only available after SDK initialization completes.
93+
* Returns NULL if not yet available.
94+
*
95+
* @param eval_context Evaluation context. Must not be NULL.
96+
* @return Environment ID as null-terminated UTF-8 string, or NULL if not
97+
* available. Valid only during the callback execution. Must not
98+
* be freed.
99+
*/
100+
LD_EXPORT(char const*)
101+
LDEvaluationSeriesContext_EnvironmentId(
102+
LDServerSDKEvaluationSeriesContext eval_context);
103+
104+
#ifdef __cplusplus
105+
}
106+
#endif
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
/**
2+
* @file evaluation_series_data.h
3+
* @brief C bindings for hook data passed between evaluation stages.
4+
*
5+
* EvaluationSeriesData is mutable data that hooks can use to pass information
6+
* from beforeEvaluation to afterEvaluation. This is useful for:
7+
* - Storing timing information
8+
* - Passing span contexts for distributed tracing
9+
* - Accumulating custom metrics
10+
*
11+
* LIFETIME AND OWNERSHIP:
12+
* - Data returned from hook callbacks transfers ownership to the SDK
13+
* - Data received in callbacks can be modified and returned (ownership transfer)
14+
* - Keys are copied by the SDK
15+
* - Values retrieved with GetValue() are temporary - valid only during callback
16+
* - Do not call LDValue_Free() on values retrieved with GetValue()
17+
* - Values stored with SetValue() are copied into the data object
18+
* - Pointers (void*) lifetime is managed by the application
19+
*
20+
* BUILDER PATTERN:
21+
* To modify data, use LDEvaluationSeriesData_NewBuilder() to create a builder,
22+
* make changes, then build a new data object.
23+
*/
24+
25+
#pragma once
26+
27+
#include <launchdarkly/bindings/c/export.h>
28+
#include <launchdarkly/bindings/c/context.h>
29+
30+
// No effect in C++, but we want it for C.
31+
// ReSharper disable once CppUnusedIncludeDirective
32+
#include <stdbool.h> // NOLINT(*-deprecated-headers)
33+
// ReSharper disable once CppUnusedIncludeDirective
34+
#include <stddef.h> // NOLINT(*-deprecated-headers)
35+
36+
#ifdef __cplusplus
37+
extern "C" {
38+
#endif
39+
40+
typedef struct p_LDServerSDKEvaluationSeriesData* LDServerSDKEvaluationSeriesData;
41+
typedef struct p_LDEvaluationSeriesDataBuilder* LDServerSDKEvaluationSeriesDataBuilder;
42+
43+
44+
/**
45+
* @brief Create a new empty evaluation series data.
46+
*
47+
* @return New data object. Must be freed with LDEvaluationSeriesData_Free()
48+
* or transferred to SDK via hook callback return.
49+
*/
50+
LD_EXPORT(LDServerSDKEvaluationSeriesData)
51+
LDEvaluationSeriesData_New(void);
52+
53+
/**
54+
* @brief Get a Value from the evaluation series data.
55+
*
56+
* LIFETIME: Returns a temporary value valid only during the callback.
57+
* Do not call LDValue_Free() on the returned value.
58+
*
59+
* USAGE:
60+
* @code
61+
* LDValue value;
62+
* if (LDEvaluationSeriesData_GetValue(data, "timestamp", &value)) {
63+
* // Use value (valid only during callback)
64+
* double timestamp = LDValue_GetNumber(value);
65+
* // Do NOT call LDValue_Free(value)
66+
* }
67+
* @endcode
68+
*
69+
* @param data Data object. Must not be NULL.
70+
* @param key Key to look up. Must be null-terminated UTF-8 string.
71+
* Must not be NULL.
72+
* @param out_value Pointer to receive the value. Must not be NULL.
73+
* Set to a temporary LDValue (valid only during callback).
74+
* Do not call LDValue_Free() on this value.
75+
* @return true if key was found and contains a Value, false otherwise.
76+
*/
77+
LD_EXPORT(bool)
78+
LDEvaluationSeriesData_GetValue(LDServerSDKEvaluationSeriesData data,
79+
char const* key,
80+
LDValue* out_value);
81+
82+
/**
83+
* @brief Get a pointer from the evaluation series data.
84+
*
85+
* Retrieves a pointer previously stored with
86+
* LDEvaluationSeriesDataBuilder_SetPointer().
87+
*
88+
* USAGE - OpenTelemetry span:
89+
* @code
90+
* void* span;
91+
* if (LDEvaluationSeriesData_GetPointer(data, "span", &span)) {
92+
* // Cast and use span
93+
* MySpan* typed_span = (MySpan*)span;
94+
* }
95+
* @endcode
96+
*
97+
* @param data Data object. Must not be NULL.
98+
* @param key Key to look up. Must be null-terminated UTF-8 string.
99+
* Must not be NULL.
100+
* @param out_pointer Pointer to receive the pointer value. Must not be NULL.
101+
* Set to NULL if key not found.
102+
* @return true if key was found and contains a pointer, false otherwise.
103+
*/
104+
LD_EXPORT(bool)
105+
LDEvaluationSeriesData_GetPointer(LDServerSDKEvaluationSeriesData data,
106+
char const* key,
107+
void** out_pointer);
108+
109+
/**
110+
* @brief Create a builder from existing data.
111+
*
112+
* Creates a builder initialized with the contents of the data object.
113+
* Use this to add or modify entries in the data.
114+
*
115+
* USAGE:
116+
* @code
117+
* LDServerSDKEvaluationSeriesDataBuilder builder =
118+
* LDEvaluationSeriesData_NewBuilder(input_data);
119+
* LDEvaluationSeriesDataBuilder_SetValue(builder, "key", value);
120+
* return LDEvaluationSeriesDataBuilder_Build(builder);
121+
* @endcode
122+
*
123+
* @param data Data to copy into builder. May be NULL (creates empty builder).
124+
* @return Builder object. Must be freed with
125+
* LDEvaluationSeriesDataBuilder_Free() or consumed with
126+
* LDEvaluationSeriesDataBuilder_Build().
127+
*/
128+
LD_EXPORT(LDServerSDKEvaluationSeriesDataBuilder)
129+
LDEvaluationSeriesData_NewBuilder(LDServerSDKEvaluationSeriesData data);
130+
131+
/**
132+
* @brief Free evaluation series data.
133+
*
134+
* Only call this if you created the data and are not returning it from
135+
* a hook callback. Data returned from callbacks is owned by the SDK.
136+
*
137+
* @param data Data to free. May be NULL (no-op).
138+
*/
139+
LD_EXPORT(void)
140+
LDEvaluationSeriesData_Free(LDServerSDKEvaluationSeriesData data);
141+
142+
/**
143+
* @brief Set a Value in the builder.
144+
*
145+
* OWNERSHIP: The value is copied/moved into the builder. You are responsible
146+
* for freeing the original value if needed.
147+
*
148+
* @param builder Builder object. Must not be NULL.
149+
* @param key Key for the value. Must be null-terminated UTF-8 string.
150+
* Must not be NULL. The key is copied.
151+
* @param value Value to store. Must not be NULL. The value is copied/moved.
152+
*/
153+
LD_EXPORT(void)
154+
LDEvaluationSeriesDataBuilder_SetValue(LDServerSDKEvaluationSeriesDataBuilder builder,
155+
char const* key,
156+
LDValue value);
157+
158+
/**
159+
* @brief Set a pointer in the builder.
160+
*
161+
* Stores an application-specific pointer. Useful for storing objects like
162+
* OpenTelemetry spans that need to be passed from beforeEvaluation to
163+
* afterEvaluation.
164+
*
165+
* LIFETIME: The pointer lifetime must extend through the evaluation series
166+
* (from beforeEvaluation through afterEvaluation).
167+
*
168+
* EXAMPLE - OpenTelemetry span:
169+
* @code
170+
* MySpan* span = start_span();
171+
* LDEvaluationSeriesDataBuilder_SetPointer(builder, "span", span);
172+
* @endcode
173+
*
174+
* @param builder Builder object. Must not be NULL.
175+
* @param key Key for the pointer. Must be null-terminated UTF-8 string.
176+
* Must not be NULL. The key is copied.
177+
* @param pointer Pointer to store. May be NULL. Lifetime managed by caller.
178+
*/
179+
LD_EXPORT(void)
180+
LDEvaluationSeriesDataBuilder_SetPointer(
181+
LDServerSDKEvaluationSeriesDataBuilder builder,
182+
char const* key,
183+
void* pointer);
184+
185+
/**
186+
* @brief Build the evaluation series data.
187+
*
188+
* Consumes the builder and creates a data object. After calling this,
189+
* do not call LDEvaluationSeriesDataBuilder_Free() on the builder.
190+
*
191+
* @param builder Builder to consume. Must not be NULL.
192+
* @return Data object. Must be freed with LDEvaluationSeriesData_Free()
193+
* or transferred to SDK via hook callback return.
194+
*/
195+
LD_EXPORT(LDServerSDKEvaluationSeriesData)
196+
LDEvaluationSeriesDataBuilder_Build(LDServerSDKEvaluationSeriesDataBuilder builder);
197+
198+
/**
199+
* @brief Free a builder without building.
200+
*
201+
* Only call this if you did not call LDEvaluationSeriesDataBuilder_Build().
202+
*
203+
* @param builder Builder to free. May be NULL (no-op).
204+
*/
205+
LD_EXPORT(void)
206+
LDEvaluationSeriesDataBuilder_Free(LDServerSDKEvaluationSeriesDataBuilder builder);
207+
208+
#ifdef __cplusplus
209+
}
210+
#endif

0 commit comments

Comments
 (0)