Skip to content

feat: try every address a contact point resolves to (DRIVER-201) - #1074

Draft
nikagra wants to merge 2 commits into
scylladb:scylla-4.xfrom
nikagra:s2/07-expand-contact-points
Draft

feat: try every address a contact point resolves to (DRIVER-201)#1074
nikagra wants to merge 2 commits into
scylladb:scylla-4.xfrom
nikagra:s2/07-expand-contact-points

Conversation

@nikagra

@nikagra nikagra commented Sep 9, 2026

Copy link
Copy Markdown

A contact point given as a hostname was one connection attempt, to whatever address Netty's resolver returned first: a dead first record failed CqlSession.build() (DRIVER-201), and the reconnection fallback from #1065 re-tried one address per round.

  • When the control connection reaches an unresolved contact point, at startup or through the fallback, the name is resolved to all of its addresses (ChannelFactory.resolveAll, feat: add resolveAll through Netty's configured resolver (DRIVER-201) #1073), deduplicated, shuffled and capped at the new advanced.connection.max-candidate-addresses (default 5); each address is tried as its own temporary node named cluster.example.com/10.0.0.1:9042, ahead of the rest of the plan.
  • AllNodesFailedException carries one entry per address; TLS and authentication keep seeing the configured name.
  • Nothing else expands: IP literals, resolved contact points, custom EndPoints and identified nodes are tried as before. A resolver failure or an unusable answer falls back to today's single connect.
  • The node reached through a contact point is registered under the labelled address (resolve() resolved, toString()/node tag gain /ip, prefix, TLS and auth name unchanged; its pool stops re-resolving the name). That is the labelled form of 4.x: the node reached through a contact-point hostname is registered under that hostname, which can later resolve to another node #1072, documented in the upgrade guide.

Verified: ControlConnectionTest +14 (8 red against the pre-expansion code, 6 pin unchanged paths), full core suite (3995) green on JDK 11, docs build; MockResolverIT against ScyllaDB 2026.1.9 including the dead-first-record case. Not covered locally: the Cassandra CCM lanes.

Stacked on #1073 (s2/06-resolve-all), which sits on scylla-4.x now that #1065 has merged.

Fixes #356
Fixes #989
Fixes #1072
Refs: #890

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Sep 9, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@nikagra
nikagra force-pushed the s2/07-expand-contact-points branch from 650e41c to aee0480 Compare September 9, 2026 22:12
@nikagra
nikagra force-pushed the s2/07-expand-contact-points branch 3 times, most recently from 5d325b7 to 9dd3b25 Compare September 10, 2026 23:03
nikagra and others added 2 commits September 11, 2026 15:25
ChannelFactory.resolveAll(SocketAddress) asks the resolver the driver's
bootstrap would use for a connect, so a custom AddressResolverGroup
installed through NettyOptions.afterBootstrapInitialized is honoured,
for every address a name currently maps to. It mirrors Netty's own
short-circuits (disabled resolver, unsupported or already-resolved
address: the input as is). AddressResolver#resolveAll resolves inline,
so the lookup runs on one pinned I/O loop, never on the caller; the
hook is asked once. No caller yet: the contact-point expansion follows.

Refs: scylladb#890

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A contact point given as a hostname was one connect: whatever address
Netty's resolver returned first. A dead first record failed build(),
and the fallback re-tried one address per round. When the control
connection reaches such a contact point it now resolves the name to all
its addresses (ChannelFactory.resolveAll), shuffles them, caps them at
advanced.connection.max-candidate-addresses and tries each as its own
temporary node labelled hostname/ip:port, so AllNodesFailedException
names every address. The node reached is registered under that address.

Fixes scylladb#989
Fixes scylladb#1072
Refs: scylladb#890

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant