#[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
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: u8zstd;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: boolMid-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: u32Cap 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: u64First post-failure sleep, in milliseconds. 0 disables
failover sleeps entirely.
Ignored when failover is false.
failover_backoff_max_ms: u64Maximum (capped) backoff between failover attempts, in milliseconds.
Ignored when failover is false.
failover_max_duration_ms: u64Wall-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: u64Per-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: u64Per-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: u64Per-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
impl ReaderConfig
Sourcepub fn validate(&self) -> Result<()>
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.
Sourcepub fn addrs(&self) -> &[Endpoint]
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.
Sourcepub fn url_for(&self, idx: usize) -> String
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.
Sourcepub fn upgrade_headers(&self) -> Vec<(&'static str, String)>
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
impl Clone for ReaderConfig
Source§fn clone(&self) -> ReaderConfig
fn clone(&self) -> ReaderConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for ReaderConfig
impl RefUnwindSafe for ReaderConfig
impl Send for ReaderConfig
impl Sync for ReaderConfig
impl Unpin for ReaderConfig
impl UnsafeUnpin for ReaderConfig
impl UnwindSafe for ReaderConfig
Blanket Implementations§
impl<T> Allocation for T
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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