Skip to content

Commit 95e9718

Browse files
authored
feat!: use C++ Server-side SDK 3.0 bindings (#31)
This PR updates the Lua SDK to build against the C++ Server-side SDK with Redis via its provided C bindings. feat: added `makeContext` for constructing single or multi-kind contexts refactor!: SDK configuration exposes new options and is organized hierarchically refactor!: remove `inlineUsersInEvents` and `userKeysFlushInterval` config options refactor!: remove global `registerLogger` function, replace with config option refactor!: remove `alias` function, replace usage with multi-kind contexts refactor!: Variation and VariationDetail now take contexts refactor!: makeUser behavior modified to construct a user-kind context
1 parent 0a112b9 commit 95e9718

13 files changed

+1638
-579
lines changed

.github/actions/ci/action.yml

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,70 @@ inputs:
88
runs:
99
using: composite
1010
steps:
11-
- uses: leafo/gh-actions-lua@35bcb06abec04ec87df82e08caa84d545348536e
11+
- name: Install Lua
12+
uses: leafo/gh-actions-lua@35bcb06abec04ec87df82e08caa84d545348536e
1213
with:
1314
luaVersion: ${{ inputs.lua-version }}
14-
- uses: leafo/gh-actions-luarocks@e65774a6386cb4f24e293dca7fc4ff89165b64c5
15-
- name: Install C Server-side SDK Dependencies
16-
shell: bash
17-
run: |
18-
sudo apt-get update -y
19-
sudo apt-get install -y libcurl4-openssl-dev
20-
sudo apt-get install -y libhiredis-dev
21-
22-
- name: Setup C Server-side SDK
23-
shell: bash
24-
run: ./scripts/build-c-server.sh
15+
- name: Install LuaRocks
16+
uses: leafo/gh-actions-luarocks@e65774a6386cb4f24e293dca7fc4ff89165b64c5
17+
- name: Install Boost
18+
id: install-boost
19+
uses: MarkusJx/install-boost@v2.4.4
20+
with:
21+
boost_version: 1.81.0
22+
platform_version: "22.04"
23+
- name: Install CPP SDK
24+
uses: ./.github/actions/install-cpp-sdk-redis
25+
with:
26+
version: launchdarkly-cpp-server-redis-source-v2.1.0
27+
path: cpp-sdk
2528

2629
- name: Build Lua Server-side SDK
2730
shell: bash
28-
run: luarocks make launchdarkly-server-sdk-1.0-0.rockspec
31+
run: |
32+
luarocks make launchdarkly-server-sdk-1.0-0.rockspec \
33+
LD_DIR=./cpp-sdk/build-dynamic/release
2934
3035
- name: Build Lua Server-side SDK with Redis
3136
shell: bash
32-
run: luarocks make launchdarkly-server-sdk-redis-1.0-0.rockspec
37+
run: |
38+
luarocks make launchdarkly-server-sdk-redis-1.0-0.rockspec \
39+
LDREDIS_DIR=./cpp-sdk/build-dynamic/release
3340
34-
- name: Run tests
41+
- name: Run Lua Server-side SDK Tests
3542
shell: bash
3643
if: ${{ ! contains(inputs.lua-version, 'jit') }}
37-
run: lua test.lua
44+
run: luarocks test launchdarkly-server-sdk-1.0-0.rockspec
45+
env:
46+
# Needed because boost isn't installed in default system paths, which is
47+
# what the C++ Server-side SDK shared object expects.
48+
LD_LIBRARY_PATH: ${{ steps.install-boost.outputs.BOOST_ROOT }}/lib
3849

39-
- name: Run tests (JIT)
50+
- name: Run Lua Server-side SDK Tests (JIT)
4051
shell: bash
4152
if: ${{ contains(inputs.lua-version, 'jit') }}
4253
run: luajit test.lua
54+
env:
55+
# Needed because boost isn't installed in default system paths, which is
56+
# what the C++ Server-side SDK shared object expects.
57+
LD_LIBRARY_PATH: ${{ steps.install-boost.outputs.BOOST_ROOT }}/lib
58+
59+
- name: Run Lua Server-side SDK with Redis Tests
60+
shell: bash
61+
if: ${{ ! contains(inputs.lua-version, 'jit') }}
62+
run: luarocks test launchdarkly-server-sdk-redis-1.0-0.rockspec
63+
env:
64+
# Needed because boost isn't installed in default system paths, which is
65+
# what the C++ Server-side SDK shared object expects. Same for hiredis which is bundled
66+
# with the SDK release.
67+
LD_LIBRARY_PATH: ${{ steps.install-boost.outputs.BOOST_ROOT }}/lib;./cpp-sdk/build-dynamic/release/lib
68+
69+
- name: Run Lua Server-side SDK with Redis Tests (JIT)
70+
shell: bash
71+
if: ${{ contains(inputs.lua-version, 'jit') }}
72+
run: luajit test-redis.lua
73+
env:
74+
# Needed because boost isn't installed in default system paths, which is
75+
# what the C++ Server-side SDK shared object expects. Same for hiredis which is bundled
76+
# with the SDK release.
77+
LD_LIBRARY_PATH: ${{ steps.install-boost.outputs.BOOST_ROOT }}/lib;./cpp-sdk/build-dynamic/release/lib
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This custom action is used because the MarkusJx/install-boost does
2+
# not include all built libraries for mac or windows builds.
3+
# Specifically, it was missing boost_json.
4+
name: Install C++ Server-side SDK with Redis Source
5+
description: 'Obtain prebuilt libraries for the Launchdarkly C++ server-side SDK with Redis Source.'
6+
inputs:
7+
version:
8+
required: true
9+
description: "Version of the C++ SDK with Redis Source."
10+
default: "v1.0.1"
11+
path:
12+
description: "Where to download the SDK."
13+
default: "cpp-sdk"
14+
15+
runs:
16+
using: composite
17+
steps:
18+
- name: Download C++ Server-side SDK with Redis Source
19+
uses: robinraju/release-downloader@efa4cd07bd0195e6cc65e9e30c251b49ce4d3e51
20+
id: download-cpp-sdk
21+
with:
22+
repository: "launchdarkly/cpp-sdks"
23+
latest: false
24+
tag: ${{ inputs.version }}
25+
fileName: linux-gcc-x64-dynamic.zip
26+
out-file-path: ${{ inputs.path }}
27+
extract: true

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
.idea
2+
cpp-sdks
3+
*.o
4+
*.so

README.md

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,57 @@ LaunchDarkly overview
1414
Supported Lua versions
1515
-----------
1616

17-
This version of the LaunchDarkly SDK is compatible with the Lua 5.1-5.3 interpreter, and LuaJIT.
17+
This version of the LaunchDarkly SDK is known to be compatible with the Lua 5.1-5.3 interpreter, and LuaJIT 2.0.5.
1818

19-
Supported C server-side SDK versions
19+
Supported C++ server-side SDK versions
2020
-----------
2121

22-
This version of the Lua server-side SDK depends on the C server-side SDK. The minimum required version is `2.1.0`, and under `3.0.0`.
22+
This version of the Lua server-side SDK depends on the LaunchDarkly C++ Server-side SDK.
23+
24+
If Redis support is desired, then it optionally depends on the C++ server-side SDK's Redis Source.
25+
26+
| Dependency | Minimum Version | Notes |
27+
|--------------------------------|------------------------------------------------------------------------------------------------------------|--------------------------------------------|
28+
| C++ Server-Side SDK | [3.3.0](https://github.com/launchdarkly/cpp-sdks/releases/tag/launchdarkly-cpp-server-v3.3.0) | Required dependency. |
29+
| C++ Server-Side SDK with Redis | [2.1.0](https://github.com/launchdarkly/cpp-sdks/releases/tag/launchdarkly-cpp-server-redis-source-v2.1.0) | Optional, if using Redis as a data source. |
30+
31+
32+
3rd Party Dependencies
33+
------------
34+
Depending on how the C++ server-side SDK was built, the Lua SDK may require additional runtime dependencies to work properly.
35+
36+
37+
| Dependency | If C++ SDK compiled with.. | Notes |
38+
|------------|------------------------------|------------------------------------------------------------------------|
39+
| OpenSSL | `LD_DYNAMIC_LINK_OPENSSL=ON` | If linking OpenSSL dynamically, it must be present on target system. |
40+
| Boost | `LD_DYNAMIC_LINK_BOOST=ON` | If linking Boost dynamically, it must be present on the target system. |
41+
42+
_Note: The CI process builds against the C++ Server-side SDK's Linux shared libraries, which were compiled with `LD_DYNAMIC_LINK_BOOST=ON` so
43+
Boost is fetched as part of the build process._
44+
2345

2446
Getting started
2547
-----------
2648

2749
Refer to the [SDK documentation](https://docs.launchdarkly.com/sdk/server-side/lua#getting-started) for instructions on getting started with using the SDK.
2850

51+
To compile the LuaRock modules:
52+
1. Install [LuaRocks](https://github.com/luarocks/luarocks/wiki/Download)
53+
2. Build the [C++ Server-side SDK](https://github.com/launchdarkly/cpp-sdks) from source using CMake, or obtain pre-built artifacts from the [releases page](https://github.com/launchdarkly/cpp-sdks/releases?q=%22launchdarkly-cpp-server%22)
54+
3. Run `luarocks make`:
55+
```bash
56+
# Base SDK
57+
luarocks make launchdarkly-server-sdk-1.0-0.rockspec \
58+
LD_DIR=./path-to-installed-cpp-sdk
59+
60+
# SDK with Redis
61+
luarocks make launchdarkly-server-sdk-redis-1.0-0.rockspec \
62+
LDREDIS_DIR=./path-to-installed-cpp-sdk
63+
```
64+
65+
Please note that the Lua SDK uses the C++ server-side SDK's C bindings, so if you're using prebuilt artifacts
66+
then only a C99 compiler is necessary.
67+
2968
Learn more
3069
-----------
3170

launchdarkly-server-sdk-1.0-0.rockspec

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package = "launchdarkly-server-sdk"
22

3+
rockspec_format = "3.0"
4+
35
version = "1.0-0"
46

57
source = {
@@ -13,18 +15,27 @@ dependencies = {
1315

1416
external_dependencies = {
1517
LD = {
16-
header = "launchdarkly/api.h"
17-
}
18+
header = "launchdarkly/server_side/bindings/c/sdk.h",
19+
library = "launchdarkly-cpp-server"
20+
},
21+
}
22+
23+
test = {
24+
type = "command",
25+
script = "test.lua"
1826
}
1927

2028
build = {
2129
type = "builtin",
2230
modules = {
2331
["launchdarkly_server_sdk"] = {
2432
sources = { "launchdarkly-server-sdk.c" },
33+
-- Uncomment to compile with debug messages, mainly to help debug parsing configuration/context
34+
-- builders.
35+
-- defines = {"DEBUG=1"},
2536
incdirs = {"$(LD_INCDIR)"},
2637
libdirs = {"$(LD_LIBDIR)"},
27-
libraries = {"ldserverapi"}
38+
libraries = {"launchdarkly-cpp-server"},
2839
}
2940
}
3041
}

launchdarkly-server-sdk-redis-1.0-0.rockspec

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package = "launchdarkly-server-sdk-redis"
22

3+
rockspec_format = "3.0"
4+
35
version = "1.0-0"
46

57
source = {
@@ -12,18 +14,24 @@ dependencies = {
1214

1315
external_dependencies = {
1416
LDREDIS = {
15-
header = "launchdarkly/store/redis.h"
17+
header = "launchdarkly/server_side/bindings/c/integrations/redis/redis_source.h",
18+
library = "launchdarkly-cpp-server-redis-source"
1619
}
1720
}
1821

22+
test = {
23+
type = "command",
24+
script = "test-redis.lua"
25+
}
26+
1927
build = {
2028
type = "builtin",
2129
modules = {
2230
["launchdarkly_server_sdk_redis"] = {
2331
sources = { "launchdarkly-server-sdk-redis.c" },
2432
incdirs = {"$(LDREDIS_INCDIR)"},
2533
libdirs = {"$(LDREDIS_LIBDIR)"},
26-
libraries = {"ldserverapi-redis"}
34+
libraries = {"launchdarkly-cpp-server-redis-source"}
2735
}
2836
}
2937
}

launchdarkly-server-sdk-redis.c

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,73 +9,51 @@ Server-side SDK for LaunchDarkly Redis store.
99
#include <stdbool.h>
1010
#include <string.h>
1111

12-
#include <launchdarkly/api.h>
13-
#include <launchdarkly/store/redis.h>
12+
#include <launchdarkly/server_side/bindings/c/integrations/redis/redis_source.h>
13+
14+
1415

1516
/***
16-
Initialize a store backend
17-
@function makeStore
18-
@tparam table fields list of configuration options
19-
@tparam[opt] string fields.host Hostname for Redis.
20-
@tparam[opt] int fields.port Port for Redis.
21-
@tparam[opt] string fields.prefix Redis key prefix for SDK values.
22-
@tparam[opt] int fields.poolSize Number of Redis connections to maintain.
23-
@return A fresh Redis store backend.
17+
Create a Redis data source, which can be used instead
18+
of a LaunchDarkly Streaming or Polling data source. This should be configured
19+
in the SDK's configuration table, under the dataSystem.lazyLoad.source property.
20+
@function makeRedisSource
21+
@tparam string uri Redis URI. Example: 'redis://localhost:6379'.
22+
@tparam string prefix Prefix to use when reading SDK data from Redis. This is prefixed to all
23+
Redis keys used by this SDK. Example: 'my-environment'.
24+
@return A new Redis data source.
2425
*/
2526
static int
26-
LuaLDRedisMakeStore(lua_State *const l)
27+
LuaLDRedisMakeSource(lua_State *const l)
2728
{
28-
struct LDRedisConfig *config;
29-
struct LDStoreInterface *storeInterface;
30-
31-
if (lua_gettop(l) != 1) {
32-
return luaL_error(l, "expecting exactly 1 argument");
33-
}
34-
35-
luaL_checktype(l, 1, LUA_TTABLE);
36-
37-
config = LDRedisConfigNew();
38-
39-
lua_getfield(l, 1, "host");
40-
41-
if (lua_isstring(l, -1)) {
42-
LDRedisConfigSetHost(config, luaL_checkstring(l, -1));
29+
if (lua_gettop(l) != 2) {
30+
return luaL_error(l, "expecting exactly 2 arguments");
4331
}
4432

45-
lua_getfield(l, 1, "prefix");
46-
47-
if (lua_isstring(l, -1)) {
48-
LDRedisConfigSetPrefix(config, luaL_checkstring(l, -1));
49-
}
5033

51-
lua_getfield(l, 1, "port");
34+
const char* uri = luaL_checkstring(l, 1);
35+
const char* prefix = luaL_checkstring(l, 2);
5236

53-
if (lua_isnumber(l, -1)) {
54-
LDRedisConfigSetPort(config, luaL_checkinteger(l, -1));
37+
struct LDServerLazyLoadRedisResult out_result;
38+
bool success = LDServerLazyLoadRedisSource_New(uri, prefix, &out_result);
39+
if (!success) {
40+
return luaL_error(l, "failed to create Redis source: %s", out_result.error_message);
5541
}
5642

57-
lua_getfield(l, 1, "poolSize");
58-
59-
if (lua_isnumber(l, -1)) {
60-
LDRedisConfigSetPoolSize(config, luaL_checkinteger(l, -1));
61-
}
62-
63-
storeInterface = LDStoreInterfaceRedisNew(config);
64-
65-
struct LDStoreInterface **i =
66-
(struct LDStoreInterface **)lua_newuserdata(l, sizeof(storeInterface));
43+
LDServerLazyLoadRedisSource *i =
44+
(LDServerLazyLoadRedisSource *) lua_newuserdata(l, sizeof(out_result.source));
6745

68-
*i = storeInterface;
46+
*i = out_result.source;
6947

70-
luaL_getmetatable(l, "LaunchDarklyStoreInterface");
48+
luaL_getmetatable(l, "LaunchDarklySourceInterface");
7149
lua_setmetatable(l, -2);
7250

7351
return 1;
7452
}
7553

7654
static const struct luaL_Reg launchdarkly_functions[] = {
77-
{ "makeStore", LuaLDRedisMakeStore },
78-
{ NULL, NULL }
55+
{ "makeRedisSource", LuaLDRedisMakeSource },
56+
{ NULL, NULL}
7957
};
8058

8159
#if !defined LUA_VERSION_NUM || LUA_VERSION_NUM==501
@@ -99,7 +77,7 @@ static void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
9977
int
10078
luaopen_launchdarkly_server_sdk_redis(lua_State *const l)
10179
{
102-
#if LUA_VERSION_NUM == 503 || LUA_VERSION_NUM == 502
80+
#if LUA_VERSION_NUM >= 502
10381
luaL_newlib(l, launchdarkly_functions);
10482
#else
10583
luaL_register(l, "launchdarkly-server-sdk-redis",

0 commit comments

Comments
 (0)