@@ -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