diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f013bc666..a90423d95 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(client-and-server-coexistence) if (LD_BUILD_REDIS_SUPPORT) add_subdirectory(hello-cpp-server-redis) + add_subdirectory(hello-c-server-redis) endif () diff --git a/examples/hello-c-server-redis/CMakeLists.txt b/examples/hello-c-server-redis/CMakeLists.txt new file mode 100644 index 000000000..0111abb24 --- /dev/null +++ b/examples/hello-c-server-redis/CMakeLists.txt @@ -0,0 +1,15 @@ +# Required for Apple Silicon support. +cmake_minimum_required(VERSION 3.19) + +project( + LaunchDarklyHelloCServerRedis + VERSION 0.1 + DESCRIPTION "LaunchDarkly Hello C Server-side SDK with Redis source" + LANGUAGES C +) + +set(THREADS_PREFER_PTHREAD_FLAG ON) +find_package(Threads REQUIRED) + +add_executable(hello-c-server-redis-source main.c) +target_link_libraries(hello-c-server-redis-source PRIVATE launchdarkly::server_redis_source Threads::Threads) diff --git a/examples/hello-c-server-redis/main.c b/examples/hello-c-server-redis/main.c new file mode 100644 index 000000000..31968c5e4 --- /dev/null +++ b/examples/hello-c-server-redis/main.c @@ -0,0 +1,119 @@ +#include + +#include + +#include + +#include +#include +#include +#include + +// Set SDK_KEY to your LaunchDarkly SKD key. +#define SDK_KEY "" + +// Set FEATURE_FLAG_KEY to the feature flag key you want to evaluate. +#define FEATURE_FLAG_KEY "my-boolean-flag" + +// Set INIT_TIMEOUT_MILLISECONDS to the amount of time you will wait for +// the client to become initialized. +#define INIT_TIMEOUT_MILLISECONDS 3000 + +// Set REDIS_URI to your own Redis instance's URI. +#define REDIS_URI "redis://localhost:6379" + +// Set REDIS_PREFIX to the prefix containing the launchdarkly +// environment data in Redis. +#define REDIS_PREFIX "launchdarkly" + +char const* get_with_env_fallback(char const* source_val, + char const* env_variable, + char const* error_msg); + +int main() { + char const* sdk_key = get_with_env_fallback( + SDK_KEY, "LD_SDK_KEY", + "Please edit main.c to set SDK_KEY to your LaunchDarkly server-side " + "SDK key " + "first.\n\nAlternatively, set the LD_SDK_KEY environment " + "variable.\n" + "The value of SDK_KEY in main.c takes priority over LD_SDK_KEY."); + + struct LDServerLazyLoadRedisResult result; + if (!LDServerLazyLoadRedisSource_New(REDIS_URI, REDIS_PREFIX, &result)) { + printf("error: couldn't instantiate Redis source: %s\n", + result.error_message); + return 1; + } + + LDServerConfigBuilder config_builder = LDServerConfigBuilder_New(sdk_key); + + LDServerLazyLoadBuilder lazy_builder = LDServerLazyLoadBuilder_New(); + LDServerLazyLoadBuilder_SourcePtr(lazy_builder, + (LDServerLazyLoadSourcePtr)result.source); + LDServerConfigBuilder_DataSystem_LazyLoad(config_builder, lazy_builder); + + LDServerConfig config = NULL; + LDStatus config_status = + LDServerConfigBuilder_Build(config_builder, &config); + if (!LDStatus_Ok(config_status)) { + printf("error: config is invalid: %s\n", LDStatus_Error(config_status)); + return 1; + } + + LDServerSDK client = LDServerSDK_New(config); + + bool initialized_successfully = false; + if (LDServerSDK_Start(client, INIT_TIMEOUT_MILLISECONDS, + &initialized_successfully)) { + if (initialized_successfully) { + printf("*** SDK successfully initialized!\n\n"); + } else { + printf("*** SDK failed to initialize\n"); + return 1; + } + } else { + printf("*** SDK initialization didn't complete in %dms\n", + INIT_TIMEOUT_MILLISECONDS); + return 1; + } + + LDContextBuilder context_builder = LDContextBuilder_New(); + LDContextBuilder_AddKind(context_builder, "user", "example-user-key"); + LDContextBuilder_Attributes_SetName(context_builder, "user", "Sandy"); + LDContext context = LDContextBuilder_Build(context_builder); + + bool flag_value = + LDServerSDK_BoolVariation(client, context, FEATURE_FLAG_KEY, false); + + printf("*** Feature flag '%s' is %s for this user\n\n", FEATURE_FLAG_KEY, + flag_value ? "true" : "false"); + + // Here we ensure that the SDK shuts down cleanly and has a chance to + // deliver analytics events to LaunchDarkly before the program exits. If + // analytics events are not delivered, the user properties and flag usage + // statistics will not appear on your dashboard. In a normal long-running + // application, the SDK would continue running and events would be delivered + // automatically in the background. + + LDContext_Free(context); + LDServerSDK_Free(client); + + return 0; +} + +char const* get_with_env_fallback(char const* source_val, + char const* env_variable, + char const* error_msg) { + if (strlen(source_val)) { + return source_val; + } + + char const* from_env = getenv(env_variable); + if (from_env && strlen(from_env)) { + return from_env; + } + + printf("*** %s\n\n", error_msg); + exit(1); +}