-
Notifications
You must be signed in to change notification settings - Fork 42
Client config reporting (3.x) — stage 1 (groundwork): SESSION_ID + DRIVER_CONFIG plumbing #973
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: scylla-3.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1443,6 +1443,26 @@ public Builder withApplicationInfo(ApplicationInfo applicationInfo) { | |
| return this; | ||
| } | ||
|
|
||
| /** | ||
| * Enables or disables driver configuration reporting, i.e. whether the control connection sends | ||
| * a {@code DRIVER_CONFIG} JSON blob describing the effective driver configuration in its | ||
| * startup options. <b>Enabled by default.</b> | ||
| * | ||
| * <p>The server stores it in {@code system.clients.client_options} — a per-node table, so only | ||
| * the node holding the control connection stores {@code DRIVER_CONFIG}; consumers must query | ||
| * and aggregate across all nodes. | ||
| * | ||
| * <p>This does not govern the {@code SESSION_ID} startup option, which every connection always | ||
| * sends (so the server can group every connection opened from this {@link Cluster}, across all | ||
| * of its {@link Session}s), regardless of this setting. | ||
| * | ||
| * @param enabled whether driver configuration reporting is enabled. | ||
| */ | ||
| public Builder withDriverConfigReporting(boolean enabled) { | ||
| configurationBuilder.withDriverConfigReporting(enabled); | ||
| return this; | ||
| } | ||
|
|
||
|
Comment on lines
+1446
to
+1465
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be enabled by default
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in |
||
| /** | ||
| * The configuration that will be used for the new cluster. | ||
| * | ||
|
|
@@ -1598,6 +1618,7 @@ private Manager( | |
| .withNettyOptions(configuration.getNettyOptions()) | ||
| .withCodecRegistry(configuration.getCodecRegistry()) | ||
| .withApplicationInfo(configuration.getApplicationInfo()) | ||
| .withDriverConfigReporting(configuration.isDriverConfigReportingEnabled()) | ||
| .build(); | ||
| } else { | ||
| this.configuration = configuration; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| /* | ||
| * Copyright ScyllaDB, Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package com.datastax.driver.core; | ||
|
|
||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import com.fasterxml.jackson.databind.node.ObjectNode; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Default {@link DriverConfigReporter}: serializes the driver configuration to the cross-driver | ||
| * {@code DRIVER_CONFIG} JSON shape, which {@link Connection.Factory} then sends in the control | ||
| * connection's {@code STARTUP} options. | ||
| * | ||
| * <p>The report is built once, when the {@link Cluster} initializes, and the resulting string is | ||
| * reused for the lifetime of that {@code Cluster} — it is never rebuilt while the session is in | ||
| * flight, so a control-connection reconnect costs nothing and always reports the same | ||
| * configuration. | ||
| */ | ||
| public class DefaultDriverConfigReporter implements DriverConfigReporter { | ||
|
|
||
| private static final Logger LOGGER = LoggerFactory.getLogger(DefaultDriverConfigReporter.class); | ||
|
|
||
| /** STARTUP option key under which the config JSON is sent. */ | ||
| public static final String DRIVER_CONFIG_KEY = "DRIVER_CONFIG"; | ||
|
|
||
| /** | ||
| * Major schema version. Adding keys is backward-compatible and does not bump this; only | ||
| * changing/removing the meaning of an existing key does. | ||
| */ | ||
| static final int SCHEMA_VERSION = 1; | ||
|
|
||
| private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); | ||
|
nikagra marked this conversation as resolved.
|
||
|
|
||
| protected final Configuration configuration; | ||
|
|
||
| public DefaultDriverConfigReporter(Configuration configuration) { | ||
| this.configuration = configuration; | ||
| } | ||
|
|
||
| @Override | ||
| public String buildReport() { | ||
| // Configuration reporting is a best-effort diagnostic aid, so any failure here (a bad config | ||
| // read, a misbehaving policy while introspecting, a serialization error) must be swallowed | ||
| // rather than allowed to propagate: it is built on the Cluster-initialization path, which must | ||
| // not fail because of a diagnostic. | ||
| try { | ||
| return buildJson(); | ||
| } catch (RuntimeException e) { | ||
| LOGGER.warn( | ||
| "Error while building the driver configuration report; skipping driver config reporting", | ||
| e); | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Builds the compact, single-line JSON configuration report. | ||
| * | ||
| * <p>Stage 1 emits only the schema {@code version}; the individual configuration groups are | ||
| * populated in {@link #populateConfig(ObjectNode)} in a later stage. | ||
| */ | ||
| protected String buildJson() { | ||
| ObjectNode root = OBJECT_MAPPER.createObjectNode(); | ||
| root.put("version", SCHEMA_VERSION); | ||
| populateConfig(root); | ||
| try { | ||
| return OBJECT_MAPPER.writeValueAsString(root); | ||
| } catch (JsonProcessingException e) { | ||
| // An in-memory node tree should never fail to serialize; never let it break connection setup. | ||
| LOGGER.warn("Failed to serialize driver configuration report; skipping DRIVER_CONFIG", e); | ||
| return null; | ||
| } | ||
| } | ||
|
nikagra marked this conversation as resolved.
|
||
|
|
||
| /** | ||
| * Populates the configuration groups onto the report root. Placeholder in Stage 1; Stage 2 fills | ||
| * in {@code connection}, {@code socket}, the policy groups, {@code query-defaults}, {@code tls}, | ||
| * etc. from {@link #configuration}. | ||
| */ | ||
| protected void populateConfig(ObjectNode root) { | ||
| // Stage 2: populate configuration groups from `configuration`. | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.