Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions handwritten/spanner/src/metrics/interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2025 Google LLC
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -48,7 +48,11 @@ export const MetricInterceptor = (options, nextCall) => {
// GFE/AFE latency if available,
// or else increase the GFE/AFE connectivity error count
if (metricsTracer) {
const serverTimingHeader = metadata.getMap()['server-timing'];
const serverTimingEntries = metadata.get('server-timing');
const serverTimingHeader =
serverTimingEntries.length > 0
? String(serverTimingEntries[0])
: undefined;
const gfeTiming =
metricsTracer?.extractGfeLatency(serverTimingHeader);
metricsTracer.gfeLatency = gfeTiming ?? null;
Expand Down
15 changes: 14 additions & 1 deletion handwritten/spanner/test/metrics/interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2025 Google LLC
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -25,13 +25,13 @@
let mockMetricsTracer: sinon.SinonStubbedInstance<MetricsTracer>;
let mockFactory: sinon.SinonStubbedInstance<MetricsTracerFactory>;
let mockNextCall: sinon.SinonStub;
let mockInterceptingCall: any;

Check warning on line 28 in handwritten/spanner/test/metrics/interceptor.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let mockListener: any;

Check warning on line 29 in handwritten/spanner/test/metrics/interceptor.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let serverTimingMetadata: any;

Check warning on line 30 in handwritten/spanner/test/metrics/interceptor.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let emptyMetadata: any;

Check warning on line 31 in handwritten/spanner/test/metrics/interceptor.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let mockStatus: any;

Check warning on line 32 in handwritten/spanner/test/metrics/interceptor.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let mockOptions: any;

Check warning on line 33 in handwritten/spanner/test/metrics/interceptor.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let capturedListener: any;

Check warning on line 34 in handwritten/spanner/test/metrics/interceptor.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected any. Specify a different type
let testMetadata: grpc.Metadata;

beforeEach(() => {
Expand Down Expand Up @@ -214,5 +214,18 @@
Status.OK,
);
});

it('reads server-timing header using metadata.get without calling metadata.getMap', () => {
const getMapSpy = sandbox.spy(serverTimingMetadata, 'getMap');
const getSpy = sandbox.spy(serverTimingMetadata, 'get');
const interceptingCall = MetricInterceptor(mockOptions, mockNextCall);
interceptingCall.start(testMetadata, mockListener);

capturedListener.onReceiveMetadata(serverTimingMetadata);

assert.strictEqual(getMapSpy.callCount, 0);
assert.strictEqual(getSpy.calledWith('server-timing'), true);
assert.strictEqual(mockMetricsTracer.extractGfeLatency.calledOnce, true);
});
});
});
Loading