-
Notifications
You must be signed in to change notification settings - Fork 3
feat: redis data source #289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ef1061e
648e202
9edacd1
09c74dd
4ccd79f
a7a9660
9ec37f6
30bfed2
62cb864
66b4c83
eb1b3ed
b9c03e2
371ab00
61ddbe7
aba2473
1538a76
7ab8c1d
3669ff5
4889549
d0ce48d
1db6db9
20abc69
5f04888
fe9e559
61a3bef
d3730a8
8f92208
8345ebb
1e6f05d
0a7340a
82d9fa1
cf5792e
86e7389
4f56358
b2cb6a4
17bcc1d
6712ac9
984efc4
648cbac
6a6a7b9
f76e6fd
d3d5ff2
caf7665
d1e1b82
78be652
3dfeebf
ab4a1fa
c1857d5
271d1b5
bee9be3
771fe74
54ecdce
b9a3059
7ccd3c9
8d64177
d4130fe
b82e93c
88cd795
60eb567
12bd033
ae02047
d83cc4f
97f554f
6d0f831
2475f7b
71be6fe
feaa919
a37623e
2fbceb0
286250d
866a2c0
30f8a2c
3112499
b00b7ca
04f615f
bc636e4
f2856a9
1676f67
7721c67
8cc183d
c684a00
11dda0d
3dc9dcb
a54c76e
683e65b
cfdbfe5
7323be1
00c3695
3d9d841
bd2c388
59b8e7b
d81c085
6ad3d55
6c291a5
5f3cdca
fb44d55
7406963
07edf29
c6f9953
ee63fa5
0f6b468
396825d
abed975
58f563e
a233eff
9030628
44d87ab
1a8162f
28e7420
cfa10bd
39514fa
e21d30d
0d83cfc
57a28c4
741cd8d
910e8a7
8a14a1d
2ca1491
a788d81
a68fe55
e693d85
706fd85
17089fe
81c5dc3
c416964
5711b7e
c3fb9be
623e174
533d3a6
094905c
f747f70
4ca20a9
d49e37b
d54ae62
e532133
e2e4d40
fb6971c
d904a77
055f40a
4b88673
f00bf07
b347f33
3ec5839
85991f4
d39703a
5f16bfe
4549146
0ca8b5d
99e4fdc
e62648f
d49690d
1cb9cb6
ff5fd5a
2d48311
753eb8e
f3afd59
af56baa
54e6953
8f9135b
58122a2
c4bd414
cb712d4
ff16434
bc5d216
ab98d99
125608c
4b79841
5751834
b465bd1
7e0ca2c
a28633e
b203908
b80b246
143f8c1
26341f6
de8f0b8
2d737b6
41b29ba
a9187f6
f07c8ac
1aaad0a
37738f9
555a1b9
b930275
2f69919
fe710b0
368dd12
c9e2e92
7ce3ba8
0f492ed
31bd830
6936b4d
5fe1a71
e20a267
f66f680
bff55ea
7bfbd98
46c95da
dcf5710
aee6029
95427db
9b01ee9
7def292
27c4fd9
0a7eff9
ec1dede
7433b9a
7344564
fc8a21b
682197c
0e0b2fc
2b0017f
0e8b17a
2959e10
0e4dc5b
42c6823
8a6890c
69e9fa9
39d08eb
4248c26
a932419
fee073b
47758b3
f9a37ac
4b361af
c18d743
c63c292
40a23e7
0f007aa
9e922c5
2994d8e
14c3cef
54ab922
623bdd8
2c28a45
b1614ca
aa8ddc0
6efb432
0fee653
f40df7b
c5e63a1
2562684
9181314
4f9e664
c4c7c32
0396c83
f8db865
b561989
2c6f35a
44a72fa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| --- | ||
| name: 'C++ Server SDK / Redis Source Bug Report' | ||
| about: Create a report to help us improve | ||
| title: '' | ||
| labels: 'package: sdk/server-redis, bug' | ||
| assignees: '' | ||
|
|
||
| --- | ||
|
|
||
| **Is this a support request?** | ||
| This issue tracker is maintained by LaunchDarkly SDK developers and is intended for feedback on the code in this | ||
| library. If you're not sure whether the problem you are having is specifically related to this library, or to the | ||
| LaunchDarkly service overall, it may be more appropriate to contact the LaunchDarkly support team; they can help to | ||
| investigate the problem and will consult the SDK team if necessary. You can submit a support request by | ||
| going [here](https://support.launchdarkly.com/) and clicking "submit a request", or by emailing | ||
| support@launchdarkly.com. | ||
|
|
||
| Note that issues filed on this issue tracker are publicly accessible. Do not provide any private account information on | ||
| your issues. If your problem is specific to your account, you should submit a support request as described above. | ||
|
|
||
| **Describe the bug** | ||
| A clear and concise description of what the bug is. | ||
|
|
||
| **To reproduce** | ||
| Steps to reproduce the behavior. | ||
|
|
||
| **Expected behavior** | ||
| A clear and concise description of what you expected to happen. | ||
|
|
||
| **Logs** | ||
| If applicable, add any log output related to your problem. | ||
| To get more logs from the SDK, change the log level using environment variable `LD_LOG_LEVEL`. For example: | ||
|
|
||
| ``` | ||
| LD_LOG_LEVEL=debug ./your-application | ||
| ``` | ||
|
|
||
| **SDK version** | ||
| The version of this SDK that you are using. | ||
|
|
||
| **Language version, developer tools** | ||
| For instance, C++17 or C11. If you are using a language that requires a separate compiler, such as C, please include the | ||
| name and version of the compiler too. | ||
|
|
||
| **OS/platform** | ||
| For instance, Ubuntu 16.04, Windows 10, or Android 4.0.3. If your code is running in a browser, please also include the | ||
| browser type and version. | ||
|
|
||
| **Additional context** | ||
| Add any other context about the problem here. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| --- | ||
| name: 'C++ Server SDK / Redis Source Feature Request' | ||
| about: Create a report to help us improve | ||
| title: '' | ||
| labels: 'package: sdk/server-redis, feature' | ||
| assignees: '' | ||
|
|
||
| --- | ||
|
|
||
| **Is your feature request related to a problem? Please describe.** | ||
| A clear and concise description of what the problem is. Ex. I would love to see the SDK [...does something new...] | ||
|
|
||
| **Describe the solution you'd like** | ||
| A clear and concise description of what you want to happen. | ||
|
|
||
| **Describe alternatives you've considered** | ||
| A clear and concise description of any alternative solutions or features you've considered. | ||
|
|
||
| **Additional context** | ||
| Add any other context about the feature request here. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| name: libs/server-sdk-redis-source | ||
|
|
||
| on: | ||
| push: | ||
| branches: [ main ] | ||
| paths-ignore: | ||
| - '**.md' #Do not need to run CI for markdown changes. | ||
| pull_request: | ||
| branches: [ "main", "feat/**" ] | ||
| paths-ignore: | ||
| - '**.md' | ||
|
|
||
| jobs: | ||
| build-test-redis: | ||
| runs-on: ubuntu-22.04 | ||
| services: | ||
| redis: | ||
| image: redis | ||
| ports: | ||
| - 6379:6379 | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: ./.github/actions/ci | ||
| with: | ||
| cmake_target: launchdarkly-cpp-server-redis-source | ||
| simulate_release: true | ||
| build-redis-mac: | ||
| runs-on: macos-12 | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: ./.github/actions/ci | ||
| with: | ||
| cmake_target: launchdarkly-cpp-server-redis-source | ||
| platform_version: 12 | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unless there's a quickfix for running Redis on the macos and windows runners, I'm going to file a ticket for adding it in the future. |
||
| run_tests: false # TODO: figure out how to run Redis service on Mac | ||
| build-test-redis-windows: | ||
| runs-on: windows-2022 | ||
| steps: | ||
| - uses: actions/checkout@v3 | ||
| - uses: ilammy/msvc-dev-cmd@v1 | ||
| - uses: ./.github/actions/ci | ||
| env: | ||
| BOOST_LIBRARY_DIR: 'C:\local\boost_1_81_0\lib64-msvc-14.3' | ||
| BOOST_LIBRARYDIR: 'C:\local\boost_1_81_0\lib64-msvc-14.3' | ||
| with: | ||
| cmake_target: launchdarkly-cpp-server-redis-source | ||
| platform_version: 2022 | ||
| toolset: msvc | ||
| run_tests: false # TODO: figure out how to run Redis service on Windows | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| cmake_minimum_required(VERSION 3.11) | ||
|
|
||
| include(FetchContent) | ||
|
|
||
|
|
||
| FetchContent_Declare(hiredis | ||
| GIT_REPOSITORY https://github.com/redis/hiredis.git | ||
| GIT_TAG 60e5075d4ac77424809f855ba3e398df7aacefe8 | ||
| GIT_SHALLOW TRUE | ||
| SOURCE_DIR _deps/hiredis | ||
| OVERRIDE_FIND_PACKAGE | ||
| ) | ||
|
|
||
|
|
||
| FetchContent_MakeAvailable(hiredis) | ||
|
|
||
| include_directories(${CMAKE_CURRENT_BINARY_DIR}/_deps) | ||
|
|
||
| set(REDIS_PLUS_PLUS_BUILD_TEST OFF CACHE BOOL "" FORCE) | ||
|
|
||
| # 1.3.7 is the last release that works with FetchContent, due to a problem with CheckSymbolExists | ||
| # when it tries to do feature detection on hiredis. | ||
| FetchContent_Declare(redis-plus-plus | ||
| GIT_REPOSITORY https://github.com/sewenew/redis-plus-plus.git | ||
| GIT_TAG 1.3.7 | ||
| GIT_SHALLOW TRUE | ||
| ) | ||
|
|
||
| FetchContent_MakeAvailable(redis-plus-plus) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Required for Apple Silicon support. | ||
| cmake_minimum_required(VERSION 3.19) | ||
|
|
||
| project( | ||
| LaunchDarklyHelloCPPServerRedisSource | ||
| VERSION 0.1 | ||
| DESCRIPTION "LaunchDarkly Hello CPP Server-side SDK with Redis source" | ||
| LANGUAGES CXX | ||
| ) | ||
|
|
||
| set(THREADS_PREFER_PTHREAD_FLAG ON) | ||
| find_package(Threads REQUIRED) | ||
|
|
||
| add_executable(hello-cpp-server-redis-source main.cpp) | ||
| target_link_libraries(hello-cpp-server-redis-source PRIVATE launchdarkly::server_redis_source Threads::Threads) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| #include <launchdarkly/context_builder.hpp> | ||
| #include <launchdarkly/server_side/client.hpp> | ||
| #include <launchdarkly/server_side/config/config_builder.hpp> | ||
|
|
||
| #include <launchdarkly/server_side/integrations/redis/redis_source.hpp> | ||
|
|
||
| #include <cstring> | ||
| #include <iostream> | ||
|
|
||
| // Set SDK_KEY to your LaunchDarkly SDK 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); | ||
| using namespace launchdarkly; | ||
| using namespace launchdarkly::server_side; | ||
|
|
||
| int main() { | ||
| char const* sdk_key = get_with_env_fallback( | ||
| SDK_KEY, "LD_SDK_KEY", | ||
| "Please edit main.cpp 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."); | ||
|
|
||
| auto config_builder = ConfigBuilder(sdk_key); | ||
|
|
||
| using LazyLoad = server_side::config::builders::LazyLoadBuilder; | ||
|
|
||
| auto redis = integrations::RedisDataSource::Create(REDIS_URI, REDIS_PREFIX); | ||
|
|
||
| if (!redis) { | ||
| std::cout << "error: redis config is invalid: " << redis.error() | ||
| << '\n'; | ||
| return 1; | ||
| } | ||
|
|
||
| config_builder.DataSystem().Method( | ||
| LazyLoad().Source(*redis).CacheRefresh(std::chrono::seconds(30))); | ||
|
|
||
| auto config = config_builder.Build(); | ||
| if (!config) { | ||
| std::cout << "error: config is invalid: " << config.error() << '\n'; | ||
| return 1; | ||
| } | ||
|
|
||
| auto client = Client(std::move(*config)); | ||
|
|
||
| auto start_result = client.StartAsync(); | ||
|
|
||
| if (auto const status = start_result.wait_for( | ||
| std::chrono::milliseconds(INIT_TIMEOUT_MILLISECONDS)); | ||
| status == std::future_status::ready) { | ||
| if (start_result.get()) { | ||
| std::cout << "*** SDK successfully initialized!\n\n"; | ||
| } else { | ||
| std::cout << "*** SDK failed to initialize\n"; | ||
| return 1; | ||
| } | ||
| } else { | ||
| std::cout << "*** SDK initialization didn't complete in " | ||
| << INIT_TIMEOUT_MILLISECONDS << "ms\n"; | ||
| return 1; | ||
| } | ||
|
|
||
| auto const context = | ||
| ContextBuilder().Kind("user", "example-user-key").Name("Sandy").Build(); | ||
|
|
||
| bool const flag_value = | ||
| client.BoolVariation(context, FEATURE_FLAG_KEY, false); | ||
|
|
||
| std::cout << "*** Feature flag '" << FEATURE_FLAG_KEY << "' is " | ||
| << (flag_value ? "true" : "false") << " for this user\n\n"; | ||
|
|
||
| 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; | ||
| } | ||
|
|
||
| if (char const* from_env = std::getenv(env_variable); | ||
| from_env && strlen(from_env)) { | ||
| return from_env; | ||
| } | ||
|
|
||
| std::cout << "*** " << error_msg << std::endl; | ||
| std::exit(1); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,6 +2,8 @@ | |
|
|
||
| #include "data_sources/data_source_status_manager.hpp" | ||
|
|
||
| #include <thread> | ||
|
|
||
| using launchdarkly::client_side::data_sources::DataSourceStatus; | ||
| using launchdarkly::client_side::data_sources::DataSourceStatusManager; | ||
| using launchdarkly::client_side::data_sources::IDataSourceStatusProvider; | ||
|
|
@@ -145,6 +147,8 @@ TEST(DataSourceStatusManagerTests, TimeIsUpdatedOnStateChange) { | |
| status_manager.SetState(DataSourceStatus::DataSourceState::kValid); | ||
|
|
||
| auto initial = status_manager.Status().StateSince(); | ||
|
|
||
| std::this_thread::sleep_for(std::chrono::milliseconds(1)); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO(add comment): This test randomly failed because the time hadn't changed at all. Not an ideal way to fix it, but we don't currently have a way to inject the time dependency. |
||
| status_manager.SetState(DataSourceStatus::DataSourceState::kInterrupted); | ||
|
|
||
| EXPECT_NE(initial.time_since_epoch().count(), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading the github docs leads me to believe I can't run the
services/redisin the Windows/Mac jobs.