Repository navigation
Default the replicator health URL to http://localhost:8090/ready like the other SDKs - #203
Merged
Merged
Conversation
Replicator mode now falls back to http://localhost:8090/ready when no health URL is configured, matching the Go, Python, Java and Ruby SDKs. The default applies to both ReplicatorMode = true and the WithReplicatorMode helper, and an explicit URL still wins. - Add ClientOptions.DefaultReplicatorHealthUrl and resolve the URL in the Schematic constructor and DatastreamClientAdapter. - Remove the constructor exception for ReplicatorMode without a URL. - Add a parameterless WithReplicatorMode() overload. The existing WithReplicatorMode(string) overload is unchanged and still rejects an explicitly passed blank URL. - Document the default in the README and XML docs. - Add tests for the default, explicit overrides and non-replicator mode. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Sep 30, 2026
bpapillon
approved these changes
Sep 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The C# SDK had no default health URL for replicator mode, unlike the other Schematic SDKs.
ClientOptions.ReplicatorHealthUrlwas nullable with no default.WithReplicatorMode(string healthUrl)required a URL and threw on an empty one.ReplicatorMode = truewithout a URL made theSchematicconstructor throwArgumentException("ReplicatorHealthUrl is required when ReplicatorMode is enabled"). WhenDatastreamClientAdapterwas constructed directly in replicator mode without a URL, it silently created noReplicatorHealthService, so the replicator was never reported ready and no cache version was available.What the other SDKs do
Go (
core/custom_options.go,WithDatastream) applies defaults after all options are processed, only when replicator mode is on:Python (
replicator_health_urldefault indatastream_client.py), Java (DatastreamOptions.DEFAULT_REPLICATOR_HEALTH_URL) and Ruby (REPLICATOR_HEALTH_URL) use the samehttp://localhost:8090/ready. An explicitly configured URL always wins.The health check interval already matches: C#'s
ReplicatorHealthServicedefaults to 30 seconds, the same as Go. The interval is not configurable fromClientOptionsin C#, so there was nothing to change there.Change
ClientOptions.DefaultReplicatorHealthUrl = "http://localhost:8090/ready".ClientOptions.ResolveReplicatorHealthUrl, internal). In replicator mode a null, empty or whitespace URL resolves to the default. Outside replicator mode it resolves to null, so no health service is created.Schematicconstructor passes the resolved URL toDatastreamClientAdapterand no longer throws whenReplicatorMode = truehas no URL.DatastreamClientAdapterapplies the same resolution, so direct construction behaves the same way.WithReplicatorMode()overload that uses the default.Compatibility
I added an overload instead of making
healthUrloptional. Both are source compatible, but an overload leaves the existingWithReplicatorMode(ClientOptions, string)signature and its contract exactly as they were. Already-compiled callers bind to the same method, and the default URL isn't baked into their call sites the way an optional parameter's default value would be. It also keepsWithReplicatorMode(null)from reading as "use the default".WithReplicatorMode(string)still throwsArgumentExceptionfor an explicitly passed null, empty or whitespace string. Passing a blank value explicitly usually means a config value that didn't load (for example, an unset environment variable). Failing fast was already the documented behavior, and silently pointing that caller at localhost could hide the misconfiguration. The exception message now points to the parameterless overload. This is a small, documented divergence from Go, whereWithReplicatorHealthURL("")falls back to the default. The property path does match Go: a blankReplicatorHealthUrlis treated as unset.The only behavior change for existing code:
ReplicatorMode = truewithout a URL now uses the default instead of throwing in theSchematicconstructor.Docs
.WithReplicatorMode(), a paragraph states the default, the 30 second poll interval, precedence and the blank-string behavior, and the options table lists.WithReplicatorMode()andReplicatorHealthUrlwith the default.ReplicatorHealthUrl,DefaultReplicatorHealthUrl, bothWithReplicatorModeoverloads and theDatastreamClientAdapterconstructor state the default.Tests
New
src/SchematicHQ.Client.Test/Datastream/ReplicatorHealthUrlDefaultTests.cs(16 tests):http://localhost:8090/readythrough theReplicatorModeproperty (null, empty and whitespace), throughWithReplicatorMode(), and end to end through theSchematicconstructor for both paths.WithReplicatorMode(url), the adapter, and theSchematicconstructor.ReplicatorHealthUrlis set.WithReplicatorMode("")andWithReplicatorMode(" ")still throw.The
Schematicconstructor tests use a Redis config withabortConnect=false, so they don't need a running Redis.Locally, with .NET SDK 9.0.109: the Release library build succeeds for all targets and all 454 tests pass.
🤖 Generated with Claude Code