Skip to content

Commit d88359b

Browse files
committed
Align kernel telemetry defaults with binding contract
Signed-off-by: Jay Xiao <jay.xiao@databricks.com>
1 parent 90c154e commit d88359b

4 files changed

Lines changed: 47 additions & 17 deletions

File tree

lib/kernel/KernelAuth.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,7 @@ export function buildKernelTelemetryOptions(
662662
| 'telemetryCircuitBreakerThreshold'
663663
| 'telemetryCircuitBreakerTimeout'
664664
>,
665+
options: Pick<ConnectionOptions, 'telemetryEnabled'> = {},
665666
) {
666667
const telemetry: KernelTelemetryOptions = {
667668
driverName: DRIVER_NAME,
@@ -676,16 +677,13 @@ export function buildKernelTelemetryOptions(
676677
localeName: getLocaleName(),
677678
charSetEncoding: 'UTF-8',
678679
processName: getProcessName(),
679-
// The JS/Thrift telemetry path always runs with a per-host circuit breaker
680-
// (`CircuitBreakerRegistry` creates one unconditionally). Enable the kernel's
681-
// breaker too so the `telemetryCircuitBreakerThreshold` / `...TimeoutMs` knobs
682-
// forwarded below actually take effect — the napi `.d.ts` documents those two
683-
// as applying only when the breaker is enabled, so if the kernel defaults it
684-
// off they would silently do nothing.
685-
telemetryCircuitBreakerEnabled: true,
686-
telemetryEnabled: (config.telemetryEnabled ?? true) && !isTelemetryDisabledByEnv(),
687680
};
688681

682+
const envDisabled = isTelemetryDisabledByEnv();
683+
if (options.telemetryEnabled !== undefined || envDisabled) {
684+
telemetry.telemetryEnabled = (options.telemetryEnabled ?? true) && !envDisabled;
685+
}
686+
689687
// `batchSize`, `flushIntervalMs`, and `closeFlushTimeoutMs` share the same napi
690688
// contract constraint as the breaker fields below (`Must be greater than zero when
691689
// supplied`), so a caller-supplied `0`/negative would forward verbatim and surface
@@ -711,11 +709,10 @@ export function buildKernelTelemetryOptions(
711709
if (Number.isFinite(config.telemetryCloseTimeoutMs) && config.telemetryCloseTimeoutMs! > 0) {
712710
telemetry.telemetryCloseFlushTimeoutMs = config.telemetryCloseTimeoutMs;
713711
}
714-
// The breaker is forced on above, and the napi contract requires threshold/timeout
715-
// to be strictly positive when it is enabled. A caller-supplied `0` (or negative)
716-
// would otherwise be forwarded verbatim and surface as a hard kernel `openSession`
717-
// rejection, so treat any non-positive value as a misconfiguration and fall back to
718-
// the kernel defaults (5 / 60000) instead.
712+
// The napi contract requires threshold/timeout to be strictly positive when
713+
// supplied. A caller-supplied `0` (or negative) would otherwise be forwarded
714+
// verbatim and surface as a hard kernel `openSession` rejection, so treat any
715+
// non-positive value as a misconfiguration and delegate to the kernel default.
719716
if (Number.isFinite(config.telemetryCircuitBreakerThreshold) && config.telemetryCircuitBreakerThreshold! > 0) {
720717
telemetry.telemetryCircuitBreakerThreshold = config.telemetryCircuitBreakerThreshold;
721718
}

lib/kernel/KernelBackend.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ export default class KernelBackend implements IBackend {
9898
this.nativeOptions = {
9999
...buildKernelConnectionOptions(options),
100100
...buildKernelRetryOptions(this.context.getConfig()),
101-
...buildKernelTelemetryOptions(this.context.getConfig()),
101+
...buildKernelTelemetryOptions(this.context.getConfig(), options),
102102
};
103103

104104
// Bridge the Rust kernel's `tracing` logs into the SAME `DBSQLLogger` the

tests/unit/kernel/_helpers/nativeOptions.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ export default function expectNativeConnectionOptions(actual: unknown, expectedR
5454
expect(rest.localeName, 'localeName').to.be.a('string').and.not.equal('');
5555
expect(rest.charSetEncoding, 'charSetEncoding').to.equal('UTF-8');
5656
expect(rest.processName, 'processName').to.be.a('string').and.not.equal('');
57-
expect(rest.telemetryEnabled, 'telemetryEnabled').to.be.a('boolean');
58-
expect(rest.telemetryCircuitBreakerEnabled, 'telemetryCircuitBreakerEnabled').to.equal(true);
5957
}
6058

6159
for (const key of [

tests/unit/kernel/execution.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,7 @@ describe('KernelBackend', () => {
576576
host: 'workspace.example',
577577
path: '/sql/1.0/warehouses/xyz',
578578
token: 'dapi-token',
579+
telemetryEnabled: false,
579580
} as ConnectionOptions);
580581

581582
await backend.openSession({});
@@ -598,7 +599,7 @@ describe('KernelBackend', () => {
598599
expect(args.telemetryMaxRetries).to.equal(2);
599600
expect(args.telemetryRetryDelayMs).to.equal(50);
600601
expect(args.telemetryCloseFlushTimeoutMs).to.equal(2_500);
601-
expect(args.telemetryCircuitBreakerEnabled).to.equal(true);
602+
expect(args.telemetryCircuitBreakerEnabled).to.equal(undefined);
602603
expect(args.telemetryCircuitBreakerThreshold).to.equal(3);
603604
expect(args.telemetryCircuitBreakerTimeoutMs).to.equal(60_000);
604605
} finally {
@@ -640,6 +641,40 @@ describe('KernelBackend', () => {
640641
}
641642
});
642643

644+
it('openSession() omits telemetryEnabled when the caller did not explicitly configure telemetry', async () => {
645+
const savedEnv = process.env.DATABRICKS_TELEMETRY_DISABLED;
646+
delete process.env.DATABRICKS_TELEMETRY_DISABLED;
647+
648+
const connection = new FakeNativeConnection();
649+
const binding = makeBinding(connection);
650+
const backend = new KernelBackend({
651+
context: makeContext(undefined, { telemetryEnabled: true }),
652+
nativeBinding: binding,
653+
});
654+
655+
try {
656+
await backend.connect({
657+
host: 'workspace.example',
658+
path: '/sql/1.0/warehouses/xyz',
659+
token: 'dapi-token',
660+
} as ConnectionOptions);
661+
await backend.openSession({});
662+
663+
const args = binding.openSessionStub.firstCall.args[0] as {
664+
telemetryEnabled?: boolean;
665+
telemetryCircuitBreakerEnabled?: boolean;
666+
};
667+
expect(args.telemetryEnabled).to.equal(undefined);
668+
expect(args.telemetryCircuitBreakerEnabled).to.equal(undefined);
669+
} finally {
670+
if (savedEnv === undefined) {
671+
delete process.env.DATABRICKS_TELEMETRY_DISABLED;
672+
} else {
673+
process.env.DATABRICKS_TELEMETRY_DISABLED = savedEnv;
674+
}
675+
}
676+
});
677+
643678
it('openSession() serializes session-level queryTags into sessionConf.QUERY_TAGS', async () => {
644679
const connection = new FakeNativeConnection();
645680
const binding = makeBinding(connection);

0 commit comments

Comments
 (0)