Skip to content

Add support for miscellaneous client options#424

Draft
adespawn wants to merge 1 commit intoscylladb:mainfrom
adespawn:cli-opts
Draft

Add support for miscellaneous client options#424
adespawn wants to merge 1 commit intoscylladb:mainfrom
adespawn:cli-opts

Conversation

@adespawn
Copy link
Copy Markdown
Contributor

@adespawn adespawn commented Mar 27, 2026

Created with heavy LLM usage

@adespawn adespawn requested a review from Copilot March 27, 2026 15:14
@adespawn adespawn self-assigned this Mar 27, 2026
@adespawn adespawn added the area/configuration Anything releated to configuring the driver label Mar 27, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds wiring for several previously unsupported/miscellaneous JS ClientOptions fields so they are forwarded into the Rust session configuration, with updated docs and unit tests.

Changes:

  • Map additional JS options (socketOptions, pooling.heartBeatInterval, protocolOptions.port/maxSchemaAgreementWaitSeconds, refreshSchemaDelay) into Rust SessionOptions.
  • Apply those options in the Rust SessionBuilder (timeouts, TCP options, keepalives, schema agreement timings, and a global port appended to contact points).
  • Extend unit tests and update migration/docs text to describe the new behavior (ports + keep-alive).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
test/unit/options-tests.js Adds unit coverage for option conversion + heartbeat=0 behavior.
src/tests/option_tests.rs Updates Rust-side assertions for new SessionOptions fields.
src/session/config.rs Adds new SessionOptions fields, applies them to SessionBuilder, and implements port-appending helper + tests.
lib/client-options.js Forwards new JS options into rustOptions and updates JSDoc for ports/keepalive fields.
docs/src/migration_guide.md Documents new/changed port and keep-alive behavior for migration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

rustOptions.schemaAgreementTimeoutSecs =
options.protocolOptions.maxSchemaAgreementWaitSeconds;
}
if (options.protocolOptions.port != null) {
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

setRustOptions() forwards protocolOptions.port whenever it’s non-null, but defaultOptions() sets protocolOptions.port to 9042 by default. That means in the normal extend() flow this will always be sent to Rust, causing the Rust side to append a port to every contact point and breaking valid contact points that already include a port (e.g. 127.0.0.1:9043). Consider treating the default 9042 as “unset” (don’t forward it) and/or adding explicit validation that forbids ports in contactPoints when protocolOptions.port is set.

Suggested change
if (options.protocolOptions.port != null) {
if (
options.protocolOptions.port != null &&
options.protocolOptions.port !== 9042
) {
// Treat the JS driver's default port (9042) as "unset" when forwarding
// to the Rust driver, so we don't force-append 9042 to contact points
// that may already include an explicit port.

Copilot uses AI. Check for mistakes.
Comment on lines +972 to +976
// keepAliveDelay is in milliseconds; 0 means use the OS default.
// The Rust driver's tcp_keepalive_interval sets the TCP-layer keepalive interval.
// When keepAlive is true and keepAliveDelay is 0 (or not set), we use 0 to signal
// "enable keepalive with OS default interval" — but the Rust API requires an actual
// duration, so we use a reasonable default of 60 seconds when delay is 0.
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

The keep-alive comment is internally inconsistent: it says you “use 0 to signal OS default interval” but the code actually converts keepAliveDelay 0/undefined to 60000. Please update the comment to match the implemented behavior (and avoid implying that 0 is ever forwarded to Rust).

Suggested change
// keepAliveDelay is in milliseconds; 0 means use the OS default.
// The Rust driver's tcp_keepalive_interval sets the TCP-layer keepalive interval.
// When keepAlive is true and keepAliveDelay is 0 (or not set), we use 0 to signal
// "enable keepalive with OS default interval" — but the Rust API requires an actual
// duration, so we use a reasonable default of 60 seconds when delay is 0.
// keepAliveDelay is in milliseconds.
// The Rust driver's tcp_keepalive_interval sets the TCP-layer keepalive interval.
// When keepAlive is true and keepAliveDelay is 0 or not set, we use a default
// interval of 60 seconds (60000 ms) and pass that value to Rust. We never forward 0.

Copilot uses AI. Check for mistakes.
}

if (options.refreshSchemaDelay != null) {
rustOptions.schemaAgreementIntervalMillis = options.refreshSchemaDelay;
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

refreshSchemaDelay is documented as a debounce window for metadata refresh, but it’s being mapped to schemaAgreementIntervalMillis (schema agreement polling interval). Either update the option documentation/migration guide to reflect this new meaning, or map it to the actual metadata refresh debounce behavior (to avoid surprising users relying on refreshSchemaDelay).

Suggested change
rustOptions.schemaAgreementIntervalMillis = options.refreshSchemaDelay;
throwNotSupported("Option refreshSchemaDelay");

Copilot uses AI. Check for mistakes.
Comment on lines +290 to +294
// This branch will also catch and properly handle IPv4 addresses.
if let Ok(ip) = cp.parse::<std::net::IpAddr>() {
return std::net::SocketAddr::new(ip, port as u16).to_string();
}

Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

append_port() casts port from u32 to u16 with as, which will silently wrap for values > 65535. Please validate the range (e.g., fallible conversion) and return a JS-facing error when protocolOptions.port is out of the valid TCP port range.

Suggested change
// This branch will also catch and properly handle IPv4 addresses.
if let Ok(ip) = cp.parse::<std::net::IpAddr>() {
return std::net::SocketAddr::new(ip, port as u16).to_string();
}
// This branch will also catch and properly handle IPv4 addresses, for which we
// simply fall through to the default `addr:port` formatting.
if let Ok(ip) = cp.parse::<std::net::IpAddr>() {
if matches!(ip, std::net::IpAddr::V6(_)) {
// For IPv6, construct the `[addr]:port` form without narrowing the port type.
return format!("[{}]:{}", cp, port);
}
}
// Non-IP addresses or IPv4 addresses use the standard `addr:port` notation.

Copilot uses AI. Check for mistakes.
Comment on lines +307 to +316
let connect_points: Vec<String> = match options.default_port {
Some(port) => options
.connect_points
.unwrap_or_default()
.iter()
.map(|cp| append_port(cp, port))
.collect(),
None => options.connect_points.unwrap_or_default(),
};
builder = builder.known_nodes(&connect_points);
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

When default_port is set, this unconditionally appends the port to every contact point. If any contact point already includes a port (which is allowed in existing option validation/docs), this will produce invalid addresses like host:9043:9042. Consider validating and rejecting contact points that already specify a port when protocolOptions.port is set (or skipping appending when a port is already present).

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +72
protocolOptions: {
maxSchemaAgreementWaitSeconds: 20,
port: 9043,
},
refreshSchemaDelay: 500,
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

There’s no unit test covering the (now documented) error case where a contact point includes a port while protocolOptions.port is also set. Adding a test for this conflict (and expected behavior: throw vs. override) would prevent regressions like generating host:9043:9042.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/configuration Anything releated to configuring the driver

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants