Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/** @file big_segments_builder.h */
// NOLINTBEGIN modernize-use-using

#pragma once

#include <launchdarkly/bindings/c/export.h>

#include <stddef.h>

#ifdef __cplusplus
extern "C" { // only need to export C interface if used by C++ source code
#endif

typedef struct _LDServerBigSegmentsBuilder* LDServerBigSegmentsBuilder;

/**
* Opaque handle to a Big Segment store implementation, produced by an
* integration library (for example, the server-side Redis or DynamoDB Big
* Segments source libraries).
*
* Behavior is undefined if the pointer does not originate from a
* LaunchDarkly-provided Big Segments integration.
*/
typedef struct _LDServerBigSegmentStorePtr* LDServerBigSegmentStorePtr;

/**
* Creates a Big Segments builder wrapping the given store.
*
* The store pointer is consumed: the SDK takes ownership of the underlying
* store and will free it when the SDK is destroyed. Do not free the store
* pointer after calling this function.
*
* If not passed into the config builder, the returned Big Segments builder
* must be manually freed with LDServerBigSegmentsBuilder_Free.
*
* @param store Big Segment store handle. Must not be NULL.
* @return A new Big Segments builder.
*/
LD_EXPORT(LDServerBigSegmentsBuilder)
LDServerBigSegmentsBuilder_New(LDServerBigSegmentStorePtr store);

/**
* Sets the maximum number of context membership lookups cached by the SDK.
* Defaults to 1000.
*
* A higher value reduces store queries for recently-referenced contexts at
* the cost of memory.
*
* @param b Big Segments builder. Must not be NULL.
* @param size Maximum cached lookups.
*/
LD_EXPORT(void)
LDServerBigSegmentsBuilder_ContextCacheSize(LDServerBigSegmentsBuilder b,
size_t size);

/**
* Sets the time-to-live for cached membership lookups. Defaults to 5 seconds.
*
* A higher value reduces store queries for any given context, but delays
* the SDK noticing membership changes. Zero is coerced to the default.
*
* @param b Big Segments builder. Must not be NULL.
* @param milliseconds Cache time-to-live.
*/
LD_EXPORT(void)
LDServerBigSegmentsBuilder_ContextCacheTimeMs(LDServerBigSegmentsBuilder b,
unsigned int milliseconds);

/**
* Sets the interval at which the SDK polls the store's metadata to determine
* availability and staleness. Defaults to 5 seconds.
*
* Zero is coerced to the default.
*
* @param b Big Segments builder. Must not be NULL.
* @param milliseconds Poll interval.
*/
LD_EXPORT(void)
LDServerBigSegmentsBuilder_StatusPollIntervalMs(LDServerBigSegmentsBuilder b,
unsigned int milliseconds);

/**
* Sets how long the SDK waits before treating store data as stale.
* Defaults to 2 minutes.
*
* If the store's last-updated timestamp falls behind the current time by
* more than this duration, evaluations report a big segments status of
* STALE and the status provider reports the store as stale. Zero is coerced
* to the default.
*
* @param b Big Segments builder. Must not be NULL.
* @param milliseconds Staleness threshold.
*/
LD_EXPORT(void)
LDServerBigSegmentsBuilder_StaleAfterMs(LDServerBigSegmentsBuilder b,
unsigned int milliseconds);

/**
* Frees a Big Segments builder. Do not call if the builder was consumed by
* the config builder.
*
* @param b Builder to free.
*/
LD_EXPORT(void)
LDServerBigSegmentsBuilder_Free(LDServerBigSegmentsBuilder b);

#ifdef __cplusplus
}
#endif

// NOLINTEND modernize-use-using
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#pragma once

#include <launchdarkly/server_side/bindings/c/config/big_segments_builder/big_segments_builder.h>
#include <launchdarkly/server_side/bindings/c/config/config.h>
#include <launchdarkly/server_side/bindings/c/config/fdv2_builder/fdv2_builder.h>
#include <launchdarkly/server_side/bindings/c/config/lazy_load_builder/lazy_load_builder.h>
Expand Down Expand Up @@ -278,6 +279,21 @@ LD_EXPORT(void)
LDServerConfigBuilder_DataSystem_FDv2(LDServerConfigBuilder b,
LDServerFDv2Builder fdv2_builder);

/**
* Configures the SDK's Big Segments behavior. The builder is automatically
* consumed.
*
* WARNING: Do not call any other LDServerBigSegmentsBuilder function on the
* provided builder after calling this function. It is undefined behavior.
*
* @param b Server config builder. Must not be NULL.
* @param big_segments The Big Segments builder. The builder is consumed; do
* not free it. Must not be NULL.
*/
LD_EXPORT(void)
LDServerConfigBuilder_BigSegments(LDServerConfigBuilder b,
LDServerBigSegmentsBuilder big_segments);

/**
* Specify if the SDK's data system should be enabled or not.
*
Expand Down
104 changes: 104 additions & 0 deletions libs/server-sdk/include/launchdarkly/server_side/bindings/c/sdk.h
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,110 @@ LDServerSDK_DataSourceStatus_Status(LDServerSDK sdk);
LD_EXPORT(void)
LDServerDataSourceStatus_Free(LDServerDataSourceStatus status);

typedef struct _LDServerBigSegmentStoreStatus* LDServerBigSegmentStoreStatus;

/**
* True if the most recent Big Segment store query or metadata poll succeeded.
* If false, Big Segment membership cannot currently be evaluated reliably.
*
* @param status The Big Segment store status. Must not be NULL.
*/
LD_EXPORT(bool)
LDServerBigSegmentStoreStatus_Available(LDServerBigSegmentStoreStatus status);

/**
* True if the Big Segment store's data has not been updated within the
* configured stale-after threshold. The data may still be queried; it is
* just older than desired.
*
* @param status The Big Segment store status. Must not be NULL.
*/
LD_EXPORT(bool)
LDServerBigSegmentStoreStatus_Stale(LDServerBigSegmentStoreStatus status);

/**
* Frees the Big Segment store status.
* @param status The Big Segment store status to free.
*/
LD_EXPORT(void)
LDServerBigSegmentStoreStatus_Free(LDServerBigSegmentStoreStatus status);

typedef void (*ServerBigSegmentStoreStatusCallbackFn)(
LDServerBigSegmentStoreStatus status,
void* user_data);

/**
* Defines a Big Segment store status listener which may be used to listen
* for changes to the Big Segment store status.
* The struct should be initialized using
* LDServerBigSegmentStoreStatusListener_Init before use.
*/
struct LDServerBigSegmentStoreStatusListener {
/**
* Callback function which is invoked for Big Segment store status
* changes.
*
* The provided pointers are only valid for the duration of the function
* call (excluding UserData, whose lifetime is controlled by the caller).
*
* @param status The updated Big Segment store status.
*/
ServerBigSegmentStoreStatusCallbackFn StatusChanged;

/**
* UserData is forwarded into callback functions.
*/
void* UserData;
};

/**
* Initializes a Big Segment store status change listener. Must be called
* before passing the listener to
* LDServerSDK_BigSegmentStoreStatus_OnStatusChange.
*
* If the StatusChanged member of the listener struct is not set (NULL),
* then the function will not register a listener. In that case the return
* value will be NULL.
*
* Create the struct, initialize the struct, set the StatusChanged handler
* and optionally UserData, and then pass the struct to
* LDServerSDK_BigSegmentStoreStatus_OnStatusChange.
*
* @param listener Listener to initialize.
*/
LD_EXPORT(void)
LDServerBigSegmentStoreStatusListener_Init(
struct LDServerBigSegmentStoreStatusListener* listener);

/**
* Listen for changes to the Big Segment store status.
*
* @param sdk SDK. Must not be NULL.
* @param listener The listener, whose StatusChanged callback will be
* invoked when the Big Segment store status changes.
*
* @return A LDListenerConnection. The connection can be freed using
* LDListenerConnection_Free and the listener can be disconnected using
* LDListenerConnection_Disconnect. NULL is returned if the listener's
* StatusChanged member is NULL.
*/
LD_EXPORT(LDListenerConnection)
LDServerSDK_BigSegmentStoreStatus_OnStatusChange(
LDServerSDK sdk,
struct LDServerBigSegmentStoreStatusListener listener);

/**
* The current status of the Big Segment store.
*
* If no store is configured, the returned status reports unavailable and
* not stale.
*
* The caller must free the returned value using
* LDServerBigSegmentStoreStatus_Free.
*/
LD_EXPORT(LDServerBigSegmentStoreStatus)
LDServerSDK_BigSegmentStoreStatus_Status(LDServerSDK sdk);

#ifdef __cplusplus
}
#endif
Expand Down
1 change: 1 addition & 0 deletions libs/server-sdk/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ target_sources(${LIBNAME}
hooks/hook_executor.cpp
bindings/c/sdk.cpp
bindings/c/builder.cpp
bindings/c/big_segments_builder.cpp
bindings/c/fdv2_builder.cpp
bindings/c/config.cpp
bindings/c/all_flags_state/all_flags_state.cpp
Expand Down
67 changes: 67 additions & 0 deletions libs/server-sdk/src/bindings/c/big_segments_builder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// NOLINTBEGIN cppcoreguidelines-pro-type-reinterpret-cast
// NOLINTBEGIN OCInconsistentNamingInspection

#include <launchdarkly/server_side/bindings/c/config/big_segments_builder/big_segments_builder.h>

#include <launchdarkly/detail/c_binding_helpers.hpp>
#include <launchdarkly/server_side/config/builders/big_segments_builder.hpp>
#include <launchdarkly/server_side/integrations/big_segments/ibig_segment_store.hpp>

#include <chrono>
#include <memory>

using namespace launchdarkly::server_side;
using namespace launchdarkly::server_side::config::builders;

#define TO_BS_BUILDER(ptr) (reinterpret_cast<BigSegmentsBuilder*>(ptr))
#define FROM_BS_BUILDER(ptr) (reinterpret_cast<LDServerBigSegmentsBuilder>(ptr))

LD_EXPORT(LDServerBigSegmentsBuilder)
LDServerBigSegmentsBuilder_New(LDServerBigSegmentStorePtr store) {
LD_ASSERT_NOT_NULL(store);

auto* raw_store = reinterpret_cast<integrations::IBigSegmentStore*>(store);
auto owned = std::shared_ptr<integrations::IBigSegmentStore>(raw_store);
return FROM_BS_BUILDER(new BigSegmentsBuilder(std::move(owned)));
}

LD_EXPORT(void)
LDServerBigSegmentsBuilder_ContextCacheSize(LDServerBigSegmentsBuilder b,
size_t size) {
LD_ASSERT_NOT_NULL(b);

TO_BS_BUILDER(b)->ContextCacheSize(size);
}

LD_EXPORT(void)
LDServerBigSegmentsBuilder_ContextCacheTimeMs(LDServerBigSegmentsBuilder b,
unsigned int milliseconds) {
LD_ASSERT_NOT_NULL(b);

TO_BS_BUILDER(b)->ContextCacheTime(std::chrono::milliseconds{milliseconds});
}

LD_EXPORT(void)
LDServerBigSegmentsBuilder_StatusPollIntervalMs(LDServerBigSegmentsBuilder b,
unsigned int milliseconds) {
LD_ASSERT_NOT_NULL(b);

TO_BS_BUILDER(b)->StatusPollInterval(
std::chrono::milliseconds{milliseconds});
}

LD_EXPORT(void)
LDServerBigSegmentsBuilder_StaleAfterMs(LDServerBigSegmentsBuilder b,
unsigned int milliseconds) {
LD_ASSERT_NOT_NULL(b);

TO_BS_BUILDER(b)->StaleAfter(std::chrono::milliseconds{milliseconds});
}

LD_EXPORT(void)
LDServerBigSegmentsBuilder_Free(LDServerBigSegmentsBuilder b) {
delete TO_BS_BUILDER(b);
}

// NOLINTEND cppcoreguidelines-pro-type-reinterpret-cast
// NOLINTEND OCInconsistentNamingInspection
11 changes: 11 additions & 0 deletions libs/server-sdk/src/bindings/c/builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,17 @@ LDServerConfigBuilder_DataSystem_FDv2(LDServerConfigBuilder b,
LDServerFDv2Builder_Free(fdv2_builder);
}

LD_EXPORT(void)
LDServerConfigBuilder_BigSegments(LDServerConfigBuilder b,
LDServerBigSegmentsBuilder big_segments) {
LD_ASSERT_NOT_NULL(b);
LD_ASSERT_NOT_NULL(big_segments);

auto* bsb = reinterpret_cast<BigSegmentsBuilder*>(big_segments);
TO_BUILDER(b)->BigSegments(std::move(*bsb));
LDServerBigSegmentsBuilder_Free(big_segments);
}

LD_EXPORT(void)
LDServerConfigBuilder_DataSystem_Enabled(LDServerConfigBuilder b,
bool const enabled) {
Expand Down
Loading
Loading