Skip to main content

ReaderConfig

Struct ReaderConfig 

Source
#[non_exhaustive]
pub struct ReaderConfig {
Show 22 fields pub tls: bool, pub path: String, pub max_version: u8, pub compression: Compression, pub compression_level: u8, pub max_batch_rows: u64, pub client_id: Option<String>, pub target: Target, pub failover: bool, pub failover_max_attempts: u32, pub failover_backoff_initial_ms: u64, pub failover_backoff_max_ms: u64, pub failover_max_duration_ms: u64, pub auth_timeout_ms: u64, pub server_info_timeout_ms: u64, pub connect_timeout_ms: u64, pub zone: Option<String>, pub auth: AuthMode, pub tls_verify: TlsVerify, pub tls_ca: CertificateAuthority, pub tls_roots: Option<PathBuf>, pub tls_roots_password: Option<String>, /* private fields */
}
Expand description

Fully validated reader configuration.

Marked #[non_exhaustive] so future config knobs (and there will be more — the failover/auth/TLS surfaces are still maturing) can be added without breaking downstream code that pattern-matches or struct-literals this type. Construct via Self::from_conf.

§Validate-before-use contract

The non-addrs fields are deliberately pub so callers can tweak a parsed config before handing it to Reader::from_config (e.g. raise failover_max_attempts for a slow-network test, swap in a different client_id). #[non_exhaustive] blocks struct-literal construction outside this crate but does not block field mutation, so a caller can set failover_backoff_max_ms = u64::MAX after parse and bypass the parse-time hard caps.

The invariant is therefore: every code path that reads these fields must run against a ReaderConfig that has passed Self::validate since its last mutation. Reader::from_config calls validate once, defensively, before opening any socket — relying on that is the supported path. If you mutate fields after Reader::from_config has returned (or share an &mut ReaderConfig across threads in a way that’s hard to reason about), call validate() again yourself before re-using the config.

addrs is pub(crate) to keep external code from mutating the address list once a Reader is built around an Arc<ReaderConfig> snapshot; read-only access is via Self::addrs.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§tls: bool§path: String§max_version: u8§compression: Compression§compression_level: u8

zstd;level=N hint advertised in X-QWP-Accept-Encoding when compression is Zstd or Auto. Ignored for Raw. Range [MIN_COMPRESSION_LEVEL, MAX_COMPRESSION_LEVEL]; the server clamps to [1, 9] per wire-egress.md §3. Default DEFAULT_COMPRESSION_LEVEL (= 1).

§max_batch_rows: u64§client_id: Option<String>§target: Target§failover: bool

Mid-query failover. When true and the transport fails after a QUERY_REQUEST has been submitted, the cursor reconnects to the next endpoint (rotating, skipping the failed one first), replays the query with a fresh request_id, and resumes from batch_seq=0 on the new connection. The user-side handler must reset any accumulated rows when notified via the ReaderQuery::on_failover_reset callback.

When false, the failover_* tunables below are accepted by the parser (so configs aren’t rejected on a partial enable/disable flip) but have no effect — transport failures surface immediately.

§failover_max_attempts: u32

Cap on total Execute() attempts for one query (default 8): the initial attempt plus at most failover_max_attempts - 1 reconnect/replay rounds. Must be >= 1. Ignored when failover is false.

§failover_backoff_initial_ms: u64

First post-failure sleep, in milliseconds. 0 disables failover sleeps entirely. Ignored when failover is false.

§failover_backoff_max_ms: u64

Maximum (capped) backoff between failover attempts, in milliseconds. Ignored when failover is false.

§failover_max_duration_ms: u64

Wall-clock budget per Execute(), in milliseconds. 0 means unbounded. Bounds failover eligibility, not total Execute wall-clock — a single WalkTracker round can run up to host_count × auth_timeout_ms after the deadline check passes. Failover.md §11.9.1 / §7.

Ignored when failover is false.

§auth_timeout_ms: u64

Per-host upper bound on the WS upgrade-response read, in milliseconds. Bounds the “TCP accepts but server never replies” blackhole that the OS connect timeout misses. Does NOT cover TCP connect, TLS handshake, or the post-upgrade SERVER_INFO frame read (those use the OS default / Self::server_info_timeout_ms respectively). Failover.md §1.1.

§server_info_timeout_ms: u64

Per-host upper bound on the post-upgrade SERVER_INFO (0x18) frame read, in milliseconds. Bounds the case where the server accepts the WS upgrade (HTTP 101) but never sends the SERVER_INFO binary frame — without this, the connect would stall indefinitely after auth_timeout_ms has already passed. Failover.md §1.1 specifies a separate 5 s budget; the knob is programmatic-only (not a connect-string key) so it tracks the Java reference’s withServerInfoTimeout surface.

§connect_timeout_ms: u64

Per-endpoint TCP connect (dial) budget, in milliseconds. 0 (the default) means “no client-imposed connect timeout”: the dial uses the OS default, which can hang for tens of seconds against a black-holed host that silently drops SYNs. When > 0, each dial is a TcpStream::connect_timeout bounded by this value (per resolved address); exceeding it surfaces crate::ErrorCode::ConnectTimeout and, under failover, advances to the next endpoint. Connect-string key: connect_timeout. Does NOT bound name resolution, the TLS handshake, the WS upgrade (see auth_timeout_ms), or the SERVER_INFO read (see server_info_timeout_ms).

§zone: Option<String>

Client’s zone identifier — opaque case-insensitive string (e.g. eu-west-1a, dc-amsterdam). When set, the host-health tracker prefers endpoints whose server-advertised zone_id matches (SERVER_INFO.zone_id gated on CAP_ZONE, or X-QuestDB-Zone header on a 421 reject). None collapses every host’s zone tier to Same (zone-blind selection). target=primary likewise collapses tiers to Same regardless of this value — writers follow the master across zones. Failover.md §1.1 / §2.

§auth: AuthMode§tls_verify: TlsVerify§tls_ca: CertificateAuthority§tls_roots: Option<PathBuf>§tls_roots_password: Option<String>

Password unlocking the tls_roots keystore.

When set, tls_roots is interpreted as a JKS or PKCS#12 keystore (auto-detected by magic) rather than a PEM bundle. Trusted-certificate entries are extracted into the rustls root store; private-key entries are ignored — this is a trust store, not a client-identity store. Mirrors the Java reference’s KeyStore.getInstance(...).load(stream, pwd) flow.

Implementations§

Source§

impl ReaderConfig

Source

pub fn from_conf<T: AsRef<str>>(conf: T) -> Result<Self>

Construct from a connect-string.

Source

pub fn validate(&self) -> Result<()>

Re-run the cap and consistency checks that from_conf enforces.

This is the enforcement half of the validate-before-use contract documented on ReaderConfig itself: pub fields keep the config ergonomic to tweak post-parse, and validate() is what any reader of those fields can rely on to have run since the last mutation. Reader::from_config calls this defensively before opening any socket; call it explicitly after mutating a config you intend to re-use through another entry point.

Source

pub fn addrs(&self) -> &[Endpoint]

Read-only view of the parsed endpoint list. The list is populated by from_conf and frozen for the lifetime of the config — this getter is the only public access path.

Source

pub fn url_for(&self, idx: usize) -> String

Build the URL for the WebSocket upgrade against the endpoint at idx in addrs. Panics if idx is out of range.

Source

pub fn url(&self) -> String

First endpoint URL — convenience for single-addr configs.

Source

pub fn upgrade_headers(&self) -> Vec<(&'static str, String)>

Build the negotiation headers as (name, value) pairs in the order the Java reference client emits them. Authorization is appended last when an auth mode is set.

Trait Implementations§

Source§

impl Clone for ReaderConfig

Source§

fn clone(&self) -> ReaderConfig

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for ReaderConfig

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Allocation for T
where T: RefUnwindSafe + Send + Sync,

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Key for T
where T: Clone,

Source§

fn align() -> usize

The alignment necessary for the key. Must return a power of two.
Source§

fn size(&self) -> usize

The size of the key in bytes.
Source§

unsafe fn init(&self, ptr: *mut u8)

Initialize the key in the given memory location. Read more
Source§

unsafe fn get<'a>(ptr: *const u8) -> &'a T

Get a reference to the key from the given memory location. Read more
Source§

unsafe fn drop_in_place(ptr: *mut u8)

Drop the key in place. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V