Skip to content

Commit d2b9a82

Browse files
committed
Implement T4 and M4
1 parent 75c76e1 commit d2b9a82

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

core/packages/gax/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
"dependencies": {
1313
"@grpc/grpc-js": "^1.12.6",
1414
"@grpc/proto-loader": "^0.8.0",
15+
"@opentelemetry/api": "^1.9.0",
1516
"duplexify": "^4.1.3",
1617
"google-auth-library": "10.5.0",
1718
"google-logging-utils": "1.1.3",

core/packages/gax/src/normalCalls/retries.ts

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import {Status} from '../status';
18+
import {trace, metrics, SpanStatusCode} from '@opentelemetry/api';
1819

1920
import {
2021
APICallback,
@@ -29,6 +30,12 @@ import {GoogleError} from '../googleError';
2930

3031
import {addTimeoutArg} from './timeout';
3132

33+
const meter = metrics.getMeter('google-gax');
34+
const attemptDurationRecorder = meter.createHistogram('gcp-e.attempt_duration', {
35+
description: 'Duration of a single gRPC attempt',
36+
unit: 'ms',
37+
});
38+
3239
/**
3340
* Creates a function equivalent to func, but that retries on certain
3441
* exceptions.
@@ -143,36 +150,57 @@ export function retryable(
143150
retries++;
144151
let lastError = err;
145152
const toCall = addTimeoutArg(func, timeout!, otherArgs);
146-
canceller = toCall(argument, (err, response, next, rawResponse) => {
147-
if (err) {
148-
lastError = err;
149-
}
150-
if (!err) {
151-
callback(null, response, next, rawResponse);
152-
return;
153-
}
154-
canceller = null;
155-
if (
156-
retry.retryCodes.length > 0 &&
157-
retry.retryCodes.indexOf(err!.code!) < 0
158-
) {
159-
err.note =
160-
'Exception occurred in retry method that was ' +
161-
'not classified as transient';
162-
callback(err);
163-
} else {
164-
const toSleep = Math.random() * delay;
165-
timeoutId = setTimeout(() => {
166-
now = new Date();
167-
delay = Math.min(delay * delayMult, maxDelay);
168-
const timeoutCal =
169-
timeout && timeoutMult ? timeout * timeoutMult : 0;
170-
const rpcTimeout = maxTimeout ? maxTimeout : 0;
171-
const newDeadline = deadline ? deadline - now.getTime() : Infinity;
172-
timeout = Math.min(timeoutCal, rpcTimeout, newDeadline);
173-
repeat(lastError);
174-
}, toSleep);
175-
}
153+
154+
const tracer = trace.getTracer('google-gax');
155+
const spanName = apiName ? `grpc.attempt.${apiName}` : 'grpc.attempt';
156+
const startTime = Date.now();
157+
158+
canceller = tracer.startActiveSpan(spanName, (span) => {
159+
const result = toCall(argument, (err, response, next, rawResponse) => {
160+
const duration = Date.now() - startTime;
161+
attemptDurationRecorder.record(duration, {
162+
'rpc.method': apiName || 'unknown',
163+
'rpc.grpc.status_code': err ? err.code || -1 : 0, // 0 is OK
164+
});
165+
166+
if (err) {
167+
lastError = err;
168+
span.setStatus({ code: SpanStatusCode.ERROR, message: err.message });
169+
console.error(`[GAPIC Attempt Error] in ${spanName}:`, err);
170+
}
171+
if (!err) {
172+
span.setStatus({ code: SpanStatusCode.OK });
173+
}
174+
span.end();
175+
176+
if (!err) {
177+
callback(null, response, next, rawResponse);
178+
return;
179+
}
180+
canceller = null;
181+
if (
182+
retry.retryCodes.length > 0 &&
183+
retry.retryCodes.indexOf(err!.code!) < 0
184+
) {
185+
err.note =
186+
'Exception occurred in retry method that was ' +
187+
'not classified as transient';
188+
callback(err);
189+
} else {
190+
const toSleep = Math.random() * delay;
191+
timeoutId = setTimeout(() => {
192+
now = new Date();
193+
delay = Math.min(delay * delayMult, maxDelay);
194+
const timeoutCal =
195+
timeout && timeoutMult ? timeout * timeoutMult : 0;
196+
const rpcTimeout = maxTimeout ? maxTimeout : 0;
197+
const newDeadline = deadline ? deadline - now.getTime() : Infinity;
198+
timeout = Math.min(timeoutCal, rpcTimeout, newDeadline);
199+
repeat(lastError);
200+
}, toSleep);
201+
}
202+
});
203+
return result;
176204
});
177205
if (canceller instanceof Promise) {
178206
canceller.catch(err => {

0 commit comments

Comments
 (0)