Skip to content

Commit 3cacf86

Browse files
kirrg001aryamohanan
authored andcommitted
refactor: added options pattern for backend connector init (#1592)
refs #1315
1 parent d467cc2 commit 3cacf86

File tree

8 files changed

+98
-61
lines changed

8 files changed

+98
-61
lines changed

packages/aws-fargate/src/activate.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,15 @@ function init() {
5454
}
5555

5656
identityProvider.init(taskArn, containerId);
57-
backendConnector.init(config, identityProvider, false, true, 950);
57+
58+
backendConnector.init({
59+
config,
60+
identityProvider,
61+
stopSendingOnFailure: false,
62+
propagateErrorsUpstream: true,
63+
defaultTimeout: 950
64+
});
65+
5866
instanaCore.init(config, backendConnector, identityProvider);
5967
metrics.activate(backendConnector);
6068
tracing.activate();

packages/aws-lambda/src/wrapper.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,15 @@ function init(event, arnInfo, _config) {
259259
}
260260

261261
identityProvider.init(arnInfo);
262-
backendConnector.init(config, identityProvider, true, false, 500, useLambdaExtension);
262+
263+
backendConnector.init({
264+
config,
265+
identityProvider,
266+
stopSendingOnFailure: true,
267+
propagateErrorsUpstream: false,
268+
defaultTimeout: 500,
269+
useLambdaExtension
270+
});
263271

264272
// instanaCore.init also normalizes the config as a side effect
265273
instanaCore.init(config, backendConnector, identityProvider);

packages/azure-container-services/src/activate.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,15 @@ function init() {
3232

3333
try {
3434
identityProvider.init();
35-
backendConnector.init(config, identityProvider, false, true, 950);
35+
36+
backendConnector.init({
37+
config,
38+
identityProvider,
39+
stopSendingOnFailure: false,
40+
propagateErrorsUpstream: true,
41+
defaultTimeout: 950
42+
});
43+
3644
instanaCore.init(config, backendConnector, identityProvider);
3745
tracing.activate();
3846

packages/google-cloud-run/src/activate.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,15 @@ function init() {
5151

5252
try {
5353
identityProvider.init(containerInstanceId);
54-
backendConnector.init(config, identityProvider, false, true, 950);
54+
55+
backendConnector.init({
56+
config,
57+
identityProvider,
58+
stopSendingOnFailure: false,
59+
propagateErrorsUpstream: true,
60+
defaultTimeout: 950
61+
});
62+
5563
instanaCore.init(config, backendConnector, identityProvider);
5664
metrics.activate(backendConnector);
5765
tracing.activate();

packages/opentelemetry-exporter/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ class InstanaExporter {
9696
instanaEnvironment.validate();
9797

9898
if (instanaEnvironment.isValid()) {
99-
instanaBackendConnector.init({ logger }, null, null, true);
99+
instanaBackendConnector.init({ config: { logger }, stopSendingOnFailure: false, propagateErrorsUpstream: true });
100100
this._isShutdown = false;
101101
}
102102
}

packages/serverless-collector/src/activate.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@ async function init() {
3131
}
3232

3333
identityProvider.init();
34-
backendConnector.init(config, identityProvider, false, true, 950);
34+
35+
backendConnector.init({
36+
config,
37+
identityProvider,
38+
stopSendingOnFailure: false,
39+
propagateErrorsUpstream: true,
40+
defaultTimeout: 950
41+
});
42+
3543
instanaCore.init(config, backendConnector, identityProvider);
3644
tracing.activate();
3745

packages/serverless/src/backend_connector.js

Lines changed: 46 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -16,37 +16,38 @@ const layerExtensionHostname = 'localhost';
1616
const layerExtensionPort = process.env.INSTANA_LAYER_EXTENSION_PORT
1717
? Number(process.env.INSTANA_LAYER_EXTENSION_PORT)
1818
: 7365;
19-
let useLambdaExtension = false;
2019

2120
const timeoutEnvVar = 'INSTANA_TIMEOUT';
22-
let defaultTimeout = 500;
2321
const layerExtensionTimeout = process.env.INSTANA_LAMBDA_EXTENSION_TIMEOUT_IN_MS
2422
? Number(process.env.INSTANA_LAMBDA_EXTENSION_TIMEOUT_IN_MS)
2523
: 500;
26-
let backendTimeout = defaultTimeout;
2724

2825
const proxyEnvVar = 'INSTANA_ENDPOINT_PROXY';
2926
let proxyAgent;
3027

31-
let stopSendingOnFailure = true;
32-
let propagateErrorsUpstream = false;
28+
const disableCaCheckEnvVar = 'INSTANA_DISABLE_CA_CHECK';
29+
const disableCaCheck = process.env[disableCaCheckEnvVar] === 'true';
30+
3331
let requestHasFailed = false;
3432
let warningsHaveBeenLogged = false;
3533

36-
const disableCaCheckEnvVar = 'INSTANA_DISABLE_CA_CHECK';
37-
const disableCaCheck = process.env[disableCaCheckEnvVar] === 'true';
34+
const defaults = {
35+
config: {},
36+
identityProvider: null,
37+
stopSendingOnFailure: true,
38+
propagateErrorsUpstream: false,
39+
defaultTimeout: 500,
40+
backendTimeout: 500,
41+
useLambdaExtension: false
42+
};
3843

44+
let options;
3945
let hostHeader;
4046

41-
exports.init = function init(
42-
config,
43-
identityProvider,
44-
_stopSendingOnFailure,
45-
_propagateErrorsUpstream,
46-
_defaultTimeout,
47-
_useLambdaExtension
48-
) {
49-
logger = config.logger;
47+
exports.init = function init(opts) {
48+
options = Object.assign(defaults, opts);
49+
50+
logger = options.config.logger;
5051

5152
if (process.env[proxyEnvVar] && !environmentUtil.sendUnencrypted) {
5253
const proxyUrl = process.env[proxyEnvVar];
@@ -65,39 +66,33 @@ exports.init = function init(
6566
);
6667
}
6768

68-
stopSendingOnFailure = _stopSendingOnFailure == null ? true : _stopSendingOnFailure;
69-
propagateErrorsUpstream = _propagateErrorsUpstream == null ? false : _propagateErrorsUpstream;
70-
defaultTimeout = _defaultTimeout == null ? defaultTimeout : _defaultTimeout;
71-
useLambdaExtension = _useLambdaExtension;
72-
backendTimeout = defaultTimeout;
73-
7469
if (process.env[timeoutEnvVar]) {
75-
backendTimeout = parseInt(process.env[timeoutEnvVar], 10);
76-
if (isNaN(backendTimeout) || backendTimeout < 0) {
70+
options.backendTimeout = parseInt(process.env[timeoutEnvVar], 10);
71+
72+
if (isNaN(options.backendTimeout) || options.backendTimeout < 0) {
7773
logger.warn(
7874
`The value of ${timeoutEnvVar} (${process.env[timeoutEnvVar]}) cannot be parsed to a valid numerical value. ` +
79-
`Will fall back to the default timeout (${defaultTimeout} ms).`
75+
`Will fall back to the default timeout (${options.defaultTimeout} ms).`
8076
);
81-
backendTimeout = defaultTimeout;
77+
78+
options.backendTimeout = 500;
8279
}
8380
}
8481

85-
if (identityProvider) {
86-
hostHeader = identityProvider.getHostHeader();
82+
if (options.identityProvider) {
83+
hostHeader = options.identityProvider.getHostHeader();
8784
if (hostHeader == null) {
8885
hostHeader = 'nodejs-serverless';
8986
}
9087
} else {
9188
hostHeader = 'nodejs-serverless';
9289
}
9390

94-
requestHasFailed = false;
95-
9691
// Heartbeat is only for the AWS Lambda extension
9792
// IMPORTANT: the @instana/aws-lambda package will not
9893
// send data once. It can happen all the time till the Lambda handler dies!
9994
// SpanBuffer sends data asap and when the handler is finished the rest is sent.
100-
if (useLambdaExtension) {
95+
if (options.useLambdaExtension) {
10196
scheduleLambdaExtensionHeartbeatRequest();
10297
}
10398
};
@@ -178,7 +173,7 @@ function scheduleLambdaExtensionHeartbeatRequest() {
178173

179174
function handleHeartbeatError(e) {
180175
// Make sure we do not try to talk to the Lambda extension again.
181-
useLambdaExtension = false;
176+
options.useLambdaExtension = false;
182177
clearInterval(heartbeatInterval);
183178

184179
logger.debug(
@@ -231,7 +226,7 @@ function getTransport(localUseLambdaExtension) {
231226
}
232227

233228
function getBackendTimeout(localUseLambdaExtension) {
234-
return localUseLambdaExtension ? layerExtensionTimeout : backendTimeout;
229+
return localUseLambdaExtension ? layerExtensionTimeout : options.backendTimeout;
235230
}
236231

237232
function send(resourcePath, payload, finalLambdaRequest, callback) {
@@ -245,9 +240,9 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
245240
// We need a local copy of the global useLambdaExtension variable, otherwise it might be changed concurrently by
246241
// scheduleLambdaExtensionHeartbeatRequest. But we need to remember the value at the time we _started_ the request to
247242
// decide whether to fall back to sending to the back end directly or give up sending data completely.
248-
let localUseLambdaExtension = useLambdaExtension;
243+
let localUseLambdaExtension = options.useLambdaExtension;
249244

250-
if (requestHasFailed && stopSendingOnFailure) {
245+
if (requestHasFailed && options.stopSendingOnFailure) {
251246
logger.info(
252247
`Not attempting to send data to ${resourcePath} as a previous request has already timed out or failed.`
253248
);
@@ -286,7 +281,7 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
286281
// serialize the payload object
287282
const serializedPayload = JSON.stringify(payload);
288283

289-
const options = {
284+
const reqOptions = {
290285
hostname: localUseLambdaExtension ? layerExtensionHostname : environmentUtil.getBackendHost(),
291286
port: localUseLambdaExtension ? layerExtensionPort : environmentUtil.getBackendPort(),
292287
path: requestPath,
@@ -300,10 +295,10 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
300295
rejectUnauthorized: !disableCaCheck
301296
};
302297

303-
options.timeout = getBackendTimeout(localUseLambdaExtension);
298+
reqOptions.timeout = getBackendTimeout(localUseLambdaExtension);
304299

305300
if (proxyAgent && !localUseLambdaExtension) {
306-
options.agent = proxyAgent;
301+
reqOptions.agent = proxyAgent;
307302
}
308303

309304
let req;
@@ -319,7 +314,7 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
319314
// report metrics and traces quite a bit. The (acceptable) downside is that we do not get to examine the response
320315
// for HTTP status codes.
321316

322-
req = transport.request(options);
317+
req = transport.request(reqOptions);
323318
} else {
324319
// If (a) our Lambda extension is available, or if (b) a user-provided proxy is in use, we do *not* apply the
325320
// optimization outlined above. Instead, we opt for the more traditional workflow of waiting until the HTTP response
@@ -329,7 +324,7 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
329324
//
330325
// See the req.end(serializedPayload) call below, too. In the no-extension/no-proxy case, that call has the callback
331326
// to end the processing. Otherwise, the callback is provided here to http.request().
332-
req = transport.request(options, () => {
327+
req = transport.request(reqOptions, () => {
333328
// When the Node.js process is frozen while the request is pending, and then thawed later,
334329
// this can trigger a stale, bogus timeout event (because from the perspective of the freshly thawed Node.js
335330
// runtime, the request has been pending and inactive since a long time). To avoid that, we remove all listeners
@@ -383,7 +378,7 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
383378
);
384379

385380
// Make sure we do not try to talk to the Lambda extension again.
386-
useLambdaExtension = localUseLambdaExtension = false;
381+
options.useLambdaExtension = localUseLambdaExtension = false;
387382
clearInterval(heartbeatInterval);
388383

389384
// Retry the request immediately, this time sending it to serverless-acceptor directly.
@@ -394,7 +389,7 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
394389
// (or a user-provided proxy).
395390
requestHasFailed = true;
396391

397-
if (!propagateErrorsUpstream) {
392+
if (!options.propagateErrorsUpstream) {
398393
if (proxyAgent) {
399394
logger.warn(
400395
'Could not send traces and metrics to Instana. Could not connect to the configured proxy ' +
@@ -409,14 +404,14 @@ function send(resourcePath, payload, finalLambdaRequest, callback) {
409404
}
410405
}
411406

412-
handleCallback(propagateErrorsUpstream ? e : undefined);
407+
handleCallback(options.propagateErrorsUpstream ? e : undefined);
413408
}
414409
});
415410

416411
req.on('finish', () => {
417412
logger.debug(`Sent data to Instana (${requestPath}).`);
418413

419-
if (useLambdaExtension && finalLambdaRequest) {
414+
if (options.useLambdaExtension && finalLambdaRequest) {
420415
clearInterval(heartbeatInterval);
421416
}
422417
});
@@ -465,7 +460,7 @@ function onTimeout(localUseLambdaExtension, req, resourcePath, payload, finalLam
465460
);
466461

467462
// Make sure we do not try to talk to the Lambda extension again.
468-
useLambdaExtension = localUseLambdaExtension = false;
463+
options.useLambdaExtension = localUseLambdaExtension = false;
469464
clearInterval(heartbeatInterval);
470465

471466
if (req && !req.destroyed) {
@@ -498,14 +493,16 @@ function onTimeout(localUseLambdaExtension, req, resourcePath, payload, finalLam
498493
}
499494

500495
const message =
501-
'Could not send traces and metrics to Instana. The Instana back end did not respond in the configured timeout ' +
502-
`of ${backendTimeout} ms. The timeout can be configured by setting the environment variable ${timeoutEnvVar}.`;
496+
'Could not send traces and metrics to Instana. The Instana back end did not respond ' +
497+
'in the configured timeout ' +
498+
`of ${options.backendTimeout} ms. The timeout can be configured by ` +
499+
`setting the environment variable ${timeoutEnvVar}.`;
503500

504-
if (!propagateErrorsUpstream) {
501+
if (!options.propagateErrorsUpstream) {
505502
logger.warn(message);
506503
}
507504

508-
handleCallback(propagateErrorsUpstream ? new Error(message) : undefined);
505+
handleCallback(options.propagateErrorsUpstream ? new Error(message) : undefined);
509506
}
510507
}
511508

packages/serverless/test/backend_connector_test.js

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ describe('[UNIT] backend connector', () => {
6363
});
6464

6565
it('when lambda extension is not used', async () => {
66-
backendConnector.init(config);
66+
backendConnector.init({ config });
6767

6868
expect(uninstrumentedHttp.http.request.called).to.be.false;
6969
await delay(750);
@@ -75,7 +75,7 @@ describe('[UNIT] backend connector', () => {
7575
it('when lambda extension is used & heartbeat is not working', async () => {
7676
expect(global.clearInterval.called).to.be.false;
7777

78-
backendConnector.init(config, null, null, null, null, true);
78+
backendConnector.init({ config, useLambdaExtension: true });
7979

8080
expect(uninstrumentedHttp.http.request.called).to.be.true;
8181
expect(uninstrumentedHttp.http.request.callCount).to.eql(1);
@@ -89,7 +89,7 @@ describe('[UNIT] backend connector', () => {
8989
it('when lambda extension is used & heartbeat is working, but timeout when talking to extension', async () => {
9090
expect(global.clearInterval.called).to.be.false;
9191

92-
backendConnector.init(config, null, null, null, null, true);
92+
backendConnector.init({ config, stopSendingOnFailure: false, useLambdaExtension: true });
9393

9494
expect(uninstrumentedHttp.http.request.called).to.be.true;
9595
expect(uninstrumentedHttp.http.request.callCount).to.eql(1);
@@ -118,7 +118,7 @@ describe('[UNIT] backend connector', () => {
118118
it('when lambda extension is used & heartbeat is working, but error when talking to extension', async () => {
119119
expect(global.clearInterval.called).to.be.false;
120120

121-
backendConnector.init(config, null, null, null, null, true);
121+
backendConnector.init({ config, useLambdaExtension: true });
122122

123123
expect(uninstrumentedHttp.http.request.called).to.be.true;
124124
expect(uninstrumentedHttp.http.request.callCount).to.eql(1);
@@ -143,7 +143,7 @@ describe('[UNIT] backend connector', () => {
143143
});
144144

145145
it('when lambda extension is used & heartbeat is working & send once', async () => {
146-
backendConnector.init(config, null, null, null, null, true);
146+
backendConnector.init({ config, useLambdaExtension: true });
147147

148148
expect(uninstrumentedHttp.http.request.called).to.be.true;
149149
expect(uninstrumentedHttp.http.request.callCount).to.eql(1);
@@ -189,7 +189,7 @@ describe('[UNIT] backend connector', () => {
189189
});
190190

191191
it('when lambda extension is used & heartbeat is working & more data is incoming', async () => {
192-
backendConnector.init(config, null, null, null, null, true);
192+
backendConnector.init({ config, useLambdaExtension: true });
193193

194194
expect(uninstrumentedHttp.http.request.called).to.be.true;
195195
expect(uninstrumentedHttp.http.request.callCount).to.eql(1);

0 commit comments

Comments
 (0)