Skip to content

feat(snippets): port /sdk/features/storing-data to canonical snippets#506

Merged
kinyoklion merged 12 commits into
mainfrom
rlamb/feature-docs-storingdata
Jun 26, 2026
Merged

feat(snippets): port /sdk/features/storing-data to canonical snippets#506
kinyoklion merged 12 commits into
mainfrom
rlamb/feature-docs-storingdata

Conversation

@kinyoklion

@kinyoklion kinyoklion commented Jun 12, 2026

Copy link
Copy Markdown
Member

Ports the entire /sdk/features/storing-data subdirectory (four pages: index, redis, dynamodb, consul) to canonical sdk-meta snippets, following the same process as the config-section port (#448) and the evaluation-reasons exemplar (#466).

Counts

  • 56 code blocks extracted into sdk-docs/features/storing-data/{index,redis,dynamodb,consul}/ across 11 server-side SDKs (.NET, C++ server, Erlang, Go, Haskell, Java, Lua, Node.js, PHP, Python, Ruby).
  • 56 bound to validators; 0 non-binds (no Objective-C sections on these pages).

Bindings

  • Parse-only scaffolds carry the Go, Node, PHP, Python, Ruby, and Lua samples as-is.
  • Compile-based validators got the store-integration add-ons staged:
    • jvm pom: launchdarkly-java-server-sdk-redis-store 3.1.1 (same addition as big-segments feat(snippets): port /sdk/features/big-segments to canonical snippets #500 — dedupe at merge), -dynamodb-store 5.0.0, -consul-store 5.0.0.
    • csharp-syntax-only requirements: LaunchDarkly.ServerSdk.Redis (also on feat(snippets): port /sdk/features/big-segments to canonical snippets #500), .DynamoDB, .Consul.
    • haskell-server image: hedis + launchdarkly-server-sdk-redis-hedis cabal deps.
    • cpp-server image/harness: cpp-sdks now configured with -DLD_BUILD_REDIS_SUPPORT=ON; a CPP_REDIS=1 env discriminator (set by the new cpp-syntax-only-redis scaffold) links launchdarkly::server_redis_source for the two Redis fragments.
    • cpp-server-v2-c validator: stub <launchdarkly/store/redis.h> + LDConfigSetFeatureStoreBackend/LDStoreInterface api.h additions for the legacy C v2 Redis fragment.

New scaffolds

  • cpp-server-sdk/scaffolds/cpp-syntax-only-redis — pre-includes the Redis source headers (native + C binding) and sets CPP_REDIS=1.
  • erlang-server-sdk/scaffolds/erlang-syntax-only-stmts — for statement sequences carrying their own clause-terminating dot.
  • haskell-server-sdk/scaffolds/haskell-syntax-only-module — compile-only (SNIPPET_CHECK=parse, new haskell-server harness path mirroring erlang-server's) for module-shaped fragments that define their own main; completes the trailing client <- makeClient config bind with an indented pure () so the published body stays verbatim.

Content fixes (inline comments on each)

Full rationale in snippets/sdks/_feature-docs-storingdata-port-notes.md:

  • .NET: LDClient -> LdClient casing (redis/dynamodb/consul); fully-qualified Consul.DataStore() call (the Consul.NET dependency's global Consul namespace shadows the integration class — CS0234 as published).
  • C++ v3 native Redis: Source(std::move(*redis_source)) (unique_ptr -> shared_ptr needs an rvalue; matches the SDK's own example).
  • C++ v3 C-binding Redis: server-side LDServerConfig/LDServerConfigBuilder_Build (published block used the client-side names), plus the (LDServerLazyLoadSourcePtr) cast from the SDK's hello-c-server-redis example.
  • Haskell Redis: configSetStoreBackend (Just backend) (v4 takes Maybe PersistentDataStore).
  • Lua v1.x (index + redis): )} -> }) syntax error.
  • Node v8 Redis (JS): destructure the named RedisFeatureStore export (module itself is not callable).
  • PHP phpredis: rewritten to the v2 integration signature the page itself prescribes (constructed Redis client first arg), per the integration README.
  • Ruby (index/redis/dynamodb/consul): LaunchDarkly::Client -> LaunchDarkly::LDClient (no Client class exists).

Validation

All 56 snippets validated locally in containers, plus regression runs of existing wrappees for every touched scaffold/validator (java + dotnet + erlang config snippets, haskell config, cpp-server v3 native, cpp-server-v2-c evaluate-context). No iOS rows on these pages, so nothing is CI-only.

Note: the jvm pom redis-store dependency and the LaunchDarkly.ServerSdk.Redis requirements line are byte-identical to the additions on the big-segments branch (#500); whichever merges second resolves trivially.


Note

Low Risk
Changes are confined to documentation snippets and compile-time validation harnesses; they do not alter production SDK runtime behavior.

Overview
Ports 56 code samples from the four storing-data doc pages (index, Redis, DynamoDB, Consul) into canonical sdk-docs/features/storing-data/ snippets for 11 server SDKs, each wired to an existing or new parse/compile validator scaffold.

Adds three scaffolds for awkward fragment shapes: cpp-syntax-only-redis (Redis headers + CPP_REDIS=1), erlang-syntax-only-stmts (bodies that end with their own .), and haskell-syntax-only-module (full modules with main, compile-only via SNIPPET_CHECK=parse).

Extends validators so store integrations type-check: JVM and .NET scaffolds pull Redis/DynamoDB/Consul packages; cpp-server enables Redis in CMake/link when CPP_REDIS=1; cpp-server-v2-c stubs <launchdarkly/store/redis.h>; Haskell adds hedis / redis-hedis and a parse-only harness path. Java, C#, and C++ scaffolds gain stubs/imports (sdkKey, SomeDatabaseName, URI/URL, etc.).

Where published MDX could not compile or run, samples are corrected inline (e.g. LdClient, fully qualified .NET Consul, C++ std::move for Redis source, Haskell Just backend, Lua }), Node v8 named RedisFeatureStore import, PHP phpredis client-first API, Ruby LaunchDarkly::LDClient). Port rationale is documented in _feature-docs-storingdata-port-notes.md.

Reviewed by Cursor Bugbot for commit 894a9ce. Bugbot is set up for automated code reviews on this repo. Configure here.

Extracts all 56 code blocks from the four storing-data pages (index,
redis, dynamodb, consul) into per-page snippet groups across 11
server-side SDKs, binds every one to a validator, and stages the
store-integration packages the compile-based validators need (jvm pom,
csharp-syntax-only requirements, haskell cabal deps, cpp-sdks redis
build). Content corrections are listed in
sdks/_feature-docs-storingdata-port-notes.md.
).CacheSeconds(30)
)
.Build();
var client = new LdClient(config);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .NET server SDK's client class is LdClient; the published new LDClient(config) is Java-style casing and does not compile.

).CacheSeconds(30)
)
.Build();
var client = new LdClient(config);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The .NET server SDK's client class is LdClient; the published new LDClient(config) is Java-style casing and does not compile.

var config = Configuration.Builder(sdkKey)
.DataStore(
Components.PersistentDataStore(
LaunchDarkly.Sdk.Server.Integrations.Consul.DataStore().Address("http://my-consul:8100")

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LaunchDarkly.ServerSdk.Consul depends on Consul.NET, which declares a global Consul namespace. C# resolves enclosing-namespace members before using-imports, so the unqualified Consul.DataStore() resolves to that namespace and fails with CS0234 in any project referencing the package; the call needs full qualification. (The new LdClient(config) line is the same .NET casing fix as the other pages.)

}

config_builder.DataSystem().Method(
LazyLoad().Source(std::move(*redis_source)).CacheRefresh(std::chrono::seconds(15))

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RedisDataSource::Create yields a unique_ptr inside the expected, and LazyLoadBuilder::Source takes a shared_ptr, which only converts from a unique_ptr rvalue -- Source(*redis_source) does not compile. The SDK's own hello-cpp-server-redis example uses std::move here.

// configured.
LDServerConfigBuilder_DataSystem_LazyLoad(cfg_builder, lazy_builder);

LDServerConfig config;

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The published block built the server config with the client-side names (LDClientConfig / LDClientConfigBuilder_Build), which don't exist in the server C binding; the server builder's output type and build function are LDServerConfig / LDServerConfigBuilder_Build. The (LDServerLazyLoadSourcePtr) cast above matches the SDK's hello-c-server-redis example -- without it the call passes an incompatible pointer type.

---

```php
$redisClient = new Redis();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The page prescribes v2 of server-sdk-redis-phpredis, whose featureRequester requires a configured Redis client instance as the first argument; the published array-options form is the removed v1.x signature. Rewritten per the integration's README, mirroring the Predis block's shape.

config = LaunchDarkly::Config.new(
feature_store: store
)
client = LaunchDarkly::LDClient.new(sdk_key, config)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ruby SDK has no LaunchDarkly::Client class; the client class is LaunchDarkly::LDClient (as this page's own DataSystem sample uses).

config = LaunchDarkly::Config.new(
feature_store: store
)
client = LaunchDarkly::LDClient.new(sdk_key, config)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ruby SDK has no LaunchDarkly::Client class; the client class is LaunchDarkly::LDClient.

config = LaunchDarkly::Config.new(
feature_store: store
)
client = LaunchDarkly::LDClient.new(sdk_key, config)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ruby SDK has no LaunchDarkly::Client class; the client class is LaunchDarkly::LDClient.

config = LaunchDarkly::Config.new(
feature_store: store
)
client = LaunchDarkly::LDClient.new(sdk_key, config)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Ruby SDK has no LaunchDarkly::Client class; the client class is LaunchDarkly::LDClient.

@kinyoklion

Copy link
Copy Markdown
Member Author

bugbot review

…oringdata

# Conflicts:
#	snippets/sdks/dotnet-server-sdk/snippets/scaffolds/csharp-syntax-only.snippet.md
#	snippets/validators/languages/cpp-server-v2-c/api.h
#	snippets/validators/languages/haskell-server/Dockerfile
@kinyoklion

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

2 issues from previous reviews remain unresolved.

Fix All in Cursor

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 5bc6b7e. Configure here.

@kinyoklion

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 9826589. Configure here.

…oringdata

# Conflicts:
#	snippets/sdks/cpp-server-sdk/snippets/scaffolds/cpp-syntax-only.snippet.md
#	snippets/sdks/dotnet-server-sdk/snippets/scaffolds/csharp-syntax-only.snippet.md
…oringdata

# Conflicts:
#	snippets/sdks/cpp-server-sdk/snippets/scaffolds/cpp-syntax-only-v2-c.snippet.md
#	snippets/validators/languages/cpp-server-v2-c/Dockerfile
…oringdata

# Conflicts:
#	snippets/sdks/cpp-server-sdk/snippets/scaffolds/cpp-syntax-only-v2-c.snippet.md
#	snippets/sdks/dotnet-server-sdk/snippets/scaffolds/csharp-syntax-only.snippet.md
#	snippets/sdks/java-server-sdk/snippets/scaffolds/java-syntax-only.snippet.md
#	snippets/validators/languages/cpp-server-v2-c/Dockerfile
@kinyoklion kinyoklion marked this pull request as ready for review June 25, 2026 22:02
@kinyoklion kinyoklion requested a review from a team as a code owner June 25, 2026 22:02
@kinyoklion

Copy link
Copy Markdown
Member Author

bugbot review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit bba4f4c. Configure here.

…oringdata

# Conflicts:
#	snippets/sdks/dotnet-server-sdk/snippets/scaffolds/csharp-syntax-only.snippet.md
#	snippets/sdks/java-server-sdk/snippets/scaffolds/java-syntax-only.snippet.md
#	snippets/validators/languages/jvm/harness/run.sh
…oringdata

# Conflicts:
#	snippets/sdks/cpp-server-sdk/snippets/scaffolds/cpp-syntax-only.snippet.md
#	snippets/sdks/java-server-sdk/snippets/scaffolds/java-syntax-only.snippet.md
The merge of origin/main (which now carries the relay-proxy daemon-mode
persistent-store stubs) duplicated the feature-store backend setter in
the v2-c api.h and the SomeDatabaseName/storeOptions stubs in the java
scaffold. Drop the redundant copies; keep one SomeDatabaseName exposing
both the `dataStore` (storing-data) and `DataStore` (daemon-mode)
spellings the snippets use.
The main merge also duplicated the persistent-store stubs in two more
scaffolds the auto-merge left without conflict markers: cpp-syntax-only
declared `sdk_key` twice with conflicting types (std::string vs
char const*), and csharp-syntax-only declared `SomeDatabaseName` as both
a dynamic field and a nested class (CS0102). Keep the std::string
sdk_key (what ConfigBuilder takes) and the dynamic SomeDatabaseName field
(resolves the snippets DataStore() call).
@kinyoklion kinyoklion merged commit ee87c66 into main Jun 26, 2026
40 checks passed
@kinyoklion kinyoklion deleted the rlamb/feature-docs-storingdata branch June 26, 2026 22:25
@github-actions github-actions Bot mentioned this pull request Jun 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants