Skip to content

Commit e2d3bb4

Browse files
DRIVER-379: Document what the configuration report describes
The guide said the report carried a version and that more keys would follow. Now that they have, it describes the three groups, shows what a default Cluster reports, and links the schema where it is maintained -- an operator reading a report may well not be reading this driver's. Five things get called out, because each is a way to misread a report rather than a detail of it: that only the default execution profile is described, that a custom policy is named and never serialized, that an absent key means "does not apply" rather than "off", that the datacenter says whether it was configured or inferred, and that the query defaults are a snapshot taken before any Session exists. The example is the real output of a default Cluster, verified against it rather than written by hand. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 907b3d2 commit e2d3bb4

2 files changed

Lines changed: 146 additions & 0 deletions

File tree

CHANGELOG.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,17 @@ Features
1414
``Cluster(driver_config_reporting_enabled=False)``; ``SESSION_ID`` is unaffected by
1515
that setting. Reporting is best effort and never prevents a connection from being
1616
established.
17+
* ``DRIVER_CONFIG`` now describes the configuration itself rather than only the schema
18+
version it follows (DRIVER-379). The report covers connection settings (timeouts,
19+
request capacity, shard awareness, socket options, reconnection policy, TLS hostname
20+
verification), the driver's own control-plane query timeouts, and the query defaults
21+
and policies a statement gets when it overrides none of them. It follows the JSON
22+
schema shared with the other ScyllaDB drivers, so the same document describes a
23+
client whichever driver wrote it. Custom policies are reported by type name only and
24+
never by their attributes, so a policy holding a credential does not leak it into the
25+
clients table.
26+
* ``Cluster.sockopts`` is now materialized at construction, so a one-shot iterable is
27+
applied to every connection the cluster opens rather than only to the first one.
1728
* Negotiate and implement the ``SCYLLA_USE_METADATA_ID`` protocol extension: prepared
1829
statements skip re-sending result metadata on EXECUTE, and the driver automatically
1930
refreshes cached metadata when the server detects a schema change (DRIVER-153)

docs/scylla-specific.rst

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,141 @@ Two of the options are about the driver rather than the protocol:
328328
driver learns to describe more of its configuration, and adding one does not
329329
bump the version.
330330

331+
The schema is shared with the other ScyllaDB drivers, so the same document
332+
describes a Go or C# client in the same terms. It is maintained
333+
`upstream
334+
<https://github.com/scylladb/gocql/blob/master/docs/driver-config-schema.json>`_.
335+
336+
What the report describes
337+
~~~~~~~~~~~~~~~~~~~~~~~~~
338+
339+
Three groups, each named for the part of the driver it covers:
340+
341+
``connection``
342+
What the driver does with a single connection: the connect timeout, how many
343+
requests one connection carries, whether pools use ScyllaDB's shard-aware
344+
port, the socket options from ``sockopts``, the reconnection policy, and --
345+
when TLS is configured -- whether the server hostname is verified.
346+
347+
``control-plane``
348+
The timeouts on the driver's own queries, the ones it runs to discover the
349+
cluster rather than on behalf of the application: ``control_connection_timeout``
350+
as a client-side limit, ``metadata_request_timeout`` as the server-side one
351+
the driver applies with ``USING TIMEOUT``, and ``max_schema_agreement_wait``.
352+
353+
``query``
354+
What a statement gets when it overrides nothing: the default consistency,
355+
serial consistency, page size, request timeout and timestamp behaviour, along
356+
with the retry, load balancing and speculative execution policies.
357+
358+
A report from a default ``Cluster()`` looks like this, reformatted -- what goes
359+
on the wire has no whitespace:
360+
361+
.. code:: json
362+
363+
{
364+
"version": 1,
365+
"connection": {
366+
"connect": {"timeout-ms": 5000},
367+
"requests": {"in-flight": {"max": 32767}, "orphaned": {"max": 24575}},
368+
"pool": {"shard-aware": {"enabled": true}},
369+
"socket": {"tcp-no-delay": false, "keep-alive": false, "reuse-address": false},
370+
"reconnection": {"policy": {"type": "exponential", "base-ms": 1000, "max-ms": 600000}}
371+
},
372+
"control-plane": {
373+
"queries": {"system": {"timeout": {"client-side-ms": 2000, "server-side-ms": 2000}}},
374+
"schema": {"agreement": {"timeout-ms": 10000}}
375+
},
376+
"query": {
377+
"defaults": {
378+
"consistency": "LOCAL_ONE",
379+
"idempotence": false,
380+
"request": {"timeout-ms": 10000},
381+
"page": {"size": 5000},
382+
"client-timestamps": true
383+
},
384+
"retry": {"policy": {"type": "standard-error-aware"}},
385+
"load-balancing": {
386+
"policy": {
387+
"type": "token-aware",
388+
"load-distribution": "shuffle",
389+
"fallback-to-non-preferred-nodes": false
390+
},
391+
"node-preference": {"type": "dc-auto"}
392+
}
393+
}
394+
}
395+
396+
Five things are worth knowing when reading one:
397+
398+
**Only the default execution profile is described.** The schema has a single
399+
``query`` group, so what it reports is the profile a statement gets when it
400+
names none -- ``EXEC_PROFILE_DEFAULT``. Policies and defaults set on other
401+
profiles do not appear. A ``load_balancing_policy`` or ``default_retry_policy``
402+
passed to the ``Cluster`` constructor is folded into that same profile, so both
403+
ways of configuring the driver read identically here.
404+
405+
**A custom policy is reported by name only.** The driver never serializes a
406+
policy object's attributes. A policy is an ordinary Python object and whatever
407+
it happens to hold -- an auth provider, a credential, a host list -- would
408+
otherwise land in the clients table for anyone who can read it. A policy the
409+
driver does not recognise is reported as
410+
``{"type": "custom", "name": "YourPolicy"}`` and nothing more, named after the
411+
policy you configured rather than whatever sits inside it.
412+
413+
The load balancing group asks a little more than that. Its built-in
414+
``token-aware`` shape carries flags describing where a request may go, so it is
415+
claimed only when *every* policy in the chain is one the driver can account for
416+
-- a token-aware policy over ``DCAwareRoundRobinPolicy``,
417+
``RackAwareRoundRobinPolicy`` or ``RoundRobinPolicy``. A chain reaching anything
418+
else is reported as custom even with a token-aware policy wrapping it, because
419+
the flags would otherwise assert plain token-aware routing and say nothing of
420+
what the inner policy does. ``WhiteListRoundRobinPolicy`` and
421+
``HostFilterPolicy`` both fall here: each confines routing to a subset of the
422+
cluster that the flags have nowhere to record.
423+
424+
``node-preference`` is reported either way -- it describes where requests go,
425+
not which policy sends them, so a ``DCAwareRoundRobinPolicy`` or
426+
``RackAwareRoundRobinPolicy`` reports its datacenter whether it is used on its
427+
own, wrapped, or sitting inside a chain reported as custom.
428+
429+
**Some keys are absent rather than false.** The schema uses absence to mean
430+
"this does not apply" or "this is not knowable", so a missing key is not a
431+
disabled setting. ``tls`` is absent when TLS is not configured;
432+
``server-side-ms`` when the connection is not to a ScyllaDB node, since
433+
``USING TIMEOUT`` is a ScyllaDB extension; ``speculative-execution`` when no
434+
speculative execution is configured; and ``client-timestamps`` when a custom
435+
``timestamp_generator`` makes it impossible to say whether the client will
436+
assign a timestamp.
437+
438+
**The datacenter says whether it was chosen or guessed.** A ``node-preference``
439+
of type ``dc`` carries a datacenter the application configured; ``dc-auto``
440+
means the driver inferred one from the first host it saw, and its ``local-dc``
441+
is absent until it has. The first report a cluster sends is usually the latter,
442+
since the control connection reports before any host has come up.
443+
444+
**``query.defaults`` is a cluster-level snapshot.** It is built when the control
445+
connection is established, before any :class:`~.Session` exists. Under execution
446+
profiles the default profile is what it describes. In legacy configuration mode
447+
the consistency, the serial consistency and the request timeout come from the
448+
``Session`` instead -- ``Session.default_consistency_level``,
449+
``default_serial_consistency_level`` and ``default_timeout``, which is where a
450+
legacy request reads them -- and ``default_fetch_size`` and
451+
``use_client_timestamp`` come from there in both modes.
452+
453+
All five live on the ``Session``, and no session exists yet when the report is
454+
built, so what is reported is the default every session created from the cluster
455+
will start with. Setting one of them on a session after ``connect()`` does not
456+
change what was reported, and is not picked up by a report a later control
457+
connection builds either.
458+
459+
Values the driver has no way to express under this schema version --
460+
``idle_heartbeat_interval``, the protocol version, compression, and non-default
461+
execution profiles -- are left out rather than approximated.
462+
463+
Reading and controlling the options
464+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
465+
331466
.. code:: python
332467
333468
from cassandra.cluster import Cluster

0 commit comments

Comments
 (0)