fix(lettuce5): decorate Redis command spans with resolved node connection for master-replica connection providers#11819
Conversation
… master/replica command span
connection for master-replica connetion providers Lettuce master/replica APIs expose a routing connection, while the concrete node connection is selected only when the command is dispatched. The existing command advice only sees the wrapper connection, so static master/replica routing can leave peer.hostname unset. Instrument the legacy MasterSlaveConnectionProvider#getConnection path and the newer MasterReplicaConnectionProvider#getConnection* paths. When a Redis command span is active, decorate it with the RedisURI from the resolved StatefulRedisConnection.
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2351d0726
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| import io.lettuce.core.RedisURI; | ||
| import io.lettuce.core.api.StatefulRedisConnection; | ||
| import io.lettuce.core.codec.StringCodec; | ||
| import io.lettuce.core.masterslave.MasterSlave; |
There was a problem hiding this comment.
Keep legacy-only test out of latest suite
This source is also compiled by latestDepTest because this module uses addTestSuiteForDir('latestDepTest', 'test') and latestDepTestImplementation depends on lettuce-core:+. The latest Lettuce 7.x no longer has the legacy io.lettuce.core.masterslave package (the production code treats it as [5,7)), so compileLatestDepTestJava/forked compile will fail on this import before tests run. Put this test in a 5.x-only source set or use the masterreplica API for the latest-dependency suite.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
I checked this against the current latest-dependency resolution. latestDepTestCompileClasspath resolves lettuce-core:+ to 7.6.0.RELEASE, and compileLatestDepTestJava --rerun-tasks succeeds.
Lettuce 7.6 still ships the public compatibility API io.lettuce.core.masterslave.MasterSlave.
Given that the MasterSlave public API exists in both our baseline 5.0 dependency and current latest 7.6 dependency, I’d prefer to keep this test in src/test for now so it runs against both versions. If Lettuce removes that compatibility API in a future release, we can then split it into a version-specific source set or add a latest-dependency variant using masterreplica.
There was a problem hiding this comment.
I changed the test so it prefers the newer master/replica API and falls back to the old one via reflection. This way, it uses the old API only before 5.2. This should keep working even if the deprecated API is removed completely.
| .and(takesArgument(0, named("io.lettuce.core.protocol.ConnectionIntent"))) | ||
| .and(returns(named("java.util.concurrent.CompletableFuture"))), |
There was a problem hiding this comment.
Add legacy async master/slave matching
For Lettuce 5.1–6, io.lettuce.core.masterslave.MasterSlaveChannelWriter.write dispatches commands through MasterSlaveConnectionProvider.getConnectionAsync(Intent), not the synchronous getConnection(Intent). This async matcher only accepts the newer io.lettuce.core.protocol.ConnectionIntent, so those legacy versions never run either advice during command dispatch and still emit master/slave command spans without the resolved connection tags.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Adding few explicit tests in e0e65be for lettuce 5.1, 6.0, 6.1, and 6.2 uncovered some missing instrumentation
Prefer the newer MasterReplica facade in the Lettuce master/replica test and fall back to the legacy MasterSlave facade when needed.
master/replica command span connection tagging across the version range.
Collapse version-specific `getConnection*` matchers to public method shape matching and keep coverage for Lettuce 5.0 through latest master/replica command span connection tagging.
|
🎯 Code Coverage (details) 🔗 Commit SHA: a63c83f | Docs | Datadog PR Page | Give us feedback! |
|
/merge |
|
View all feedbacks in Devflow UI.
The expected merge time in Use ⏳ Processing |
What Does This Do
Decorates Redis command spans with resolved node connection for master-replica connection providers
Before (no hostname) and After (hostname and other resolved connection related tags present):
Motivation
Redis command span missing
hostnameand other connection related tags when run with a master/replica connectionAdditional Notes
Lettuce master/replica APIs expose a routing connection, while the concrete node connection is selected only when the command is dispatched.
The existing command advice only sees the wrapper connection, so static master/replica routing can leave
peer.hostnameunset.Instrument the legacy
MasterSlaveConnectionProvider.getConnectionpath and the newerMasterReplicaConnectionProvider.getConnection*paths. When a Redis command span is active, decorate it with theRedisURIfrom the resolvedStatefulRedisConnection.Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issueUse
solvesinstead, and assign the PR milestone to the issue/merge. You can also:/merge --commit-message "..."/merge -c/merge -f --reason "reason"; please use this judiciously, as some checks do not run at the PR-level (note: the PR still needs to be mergeable, this will only skip the pre-merge build)Jira ticket: APMS-19871