@instana/shared-metrics 1.134.0 → 1.137.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [1.137.1](https://github.com/instana/nodejs/compare/v1.137.0...v1.137.1) (2021-11-23)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * **dependency:** pinned semver to 7.3.3 ([d32f23e](https://github.com/instana/nodejs/commit/d32f23ea6807989d57ec6165c407b64e04d8d7c1)), closes [/github.com/npm/node-semver/blob/v7.3.3/package.json#L39](https://github.com//github.com/npm/node-semver/blob/v7.3.3/package.json/issues/L39) [/github.com/npm/node-semver/blob/v7.3.5/package.json#L39](https://github.com//github.com/npm/node-semver/blob/v7.3.5/package.json/issues/L39)
12
+ * **dependency:** updated tar to 6.x in shared-metrics ([#415](https://github.com/instana/nodejs/issues/415)) ([5288ba5](https://github.com/instana/nodejs/commit/5288ba5241acd23d54f11c76edb3cffc0ffe6a66))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@instana/shared-metrics",
3
- "version": "1.134.0",
3
+ "version": "1.137.1",
4
4
  "description": "Internal metrics plug-in package for Node.js monitoring with Instana",
5
5
  "author": {
6
6
  "name": "Bastian Krol",
@@ -26,7 +26,7 @@
26
26
  "scripts": {
27
27
  "audit": "bin/prepare-audit.sh && npm audit --production; AUDIT_RESULT=$?; git checkout package-lock.json; exit $AUDIT_RESULT",
28
28
  "test": "npm run test:mocha",
29
- "test:mocha": "mocha --sort --reporter mocha-multi --reporter-options spec=-,xunit=../../test-results/shared-metris/results.xml $(find test -iname '*test.js' -not -path '*node_modules*')",
29
+ "test:mocha": "echo \"******* Files to be tested:\n $CI_SHARED_METRICS_TEST_FILES\" && mocha --sort --reporter mocha-multi --reporter-options spec=-,xunit=../../test-results/shared-metrics/results.xml ${CI_SHARED_METRICS_TEST_FILES:=$(find test -iname '*test.js' -not -path '*node_modules*')} test/globalHooks_test.js",
30
30
  "test:debug": "WITH_STDOUT=true npm run test:mocha",
31
31
  "lint": "eslint src test",
32
32
  "verify": "npm run lint && npm test",
@@ -52,6 +52,14 @@
52
52
  {
53
53
  "name": "Richard Gebhardt",
54
54
  "email": "gebhardt@us.ibm.com"
55
+ },
56
+ {
57
+ "name": "Willian Carvalho",
58
+ "email": "willian.carvalho@instana.com"
59
+ },
60
+ {
61
+ "name": "Katharina Irrgang",
62
+ "email": "katharina.irrgang@instana.com"
55
63
  }
56
64
  ],
57
65
  "bugs": {
@@ -59,13 +67,15 @@
59
67
  },
60
68
  "license": "MIT",
61
69
  "dependencies": {
62
- "@instana/core": "1.134.0",
70
+ "@instana/core": "1.137.1",
63
71
  "detect-libc": "^1.0.3",
64
72
  "event-loop-lag": "^1.4.0",
65
73
  "recursive-copy": "^2.0.13",
66
- "tar": "^5.0.11"
74
+ "semver": "7.3.3",
75
+ "tar": "^6.1.11"
67
76
  },
68
77
  "devDependencies": {
78
+ "@types/tar": "^4.0.5",
69
79
  "eslint": "^7.30.0",
70
80
  "eslint-config-airbnb-base": "^14.2.1",
71
81
  "eslint-plugin-import": "^2.23.4",
@@ -75,8 +85,7 @@
75
85
  },
76
86
  "optionalDependencies": {
77
87
  "event-loop-stats": "1.3.0",
78
- "gcstats.js": "1.0.0",
79
- "node-gyp": "^7.1.2"
88
+ "gcstats.js": "1.0.0"
80
89
  },
81
- "gitHead": "222ed99d7ce0fa90529e071a9395d726eafa9fb6"
90
+ "gitHead": "3245c3c62510c75760763669a4834c789e75fa91"
82
91
  }
@@ -7,7 +7,6 @@
7
7
 
8
8
  const path = require('path');
9
9
  const fs = require('fs');
10
-
11
10
  const { applicationUnderMonitoring } = require('@instana/core').util;
12
11
 
13
12
  let logger = require('@instana/core').logger.getLogger('metrics');
@@ -32,6 +31,7 @@ exports.payloadPrefix = 'dependencies';
32
31
  const preliminaryPayload = {};
33
32
 
34
33
  /** @type {Object.<string, *>} */
34
+ // @ts-ignore: Cannot redeclare exported variable 'currentPayload'
35
35
  exports.currentPayload = {};
36
36
 
37
37
  exports.MAX_ATTEMPTS = 20;
@@ -43,14 +43,14 @@ exports.activate = function activate() {
43
43
  attempts++;
44
44
 
45
45
  const started = Date.now();
46
- applicationUnderMonitoring.getMainPackageJsonPathStartingAtMainModule((err, packageJsonPath) => {
46
+ applicationUnderMonitoring.getMainPackageJsonPathStartingAtMainModule((err, mainPackageJsonPath) => {
47
47
  if (err) {
48
48
  return logger.warn('Failed to determine main package.json. Reason: %s %s ', err.message, err.stack);
49
- } else if (!packageJsonPath && attempts < exports.MAX_ATTEMPTS) {
49
+ } else if (!mainPackageJsonPath && attempts < exports.MAX_ATTEMPTS) {
50
50
  logger.debug('Main package.json could not be found. Will try again later.');
51
51
  setTimeout(exports.activate, DELAY).unref();
52
52
  return;
53
- } else if (!packageJsonPath) {
53
+ } else if (!mainPackageJsonPath) {
54
54
  logger.info(
55
55
  `Main package.json could not be found after ${attempts} retries. Looking for node_modules folder now.`
56
56
  );
@@ -70,11 +70,11 @@ exports.activate = function activate() {
70
70
 
71
71
  let dependencyDir;
72
72
  if (applicationUnderMonitoring.isAppInstalledIntoNodeModules()) {
73
- dependencyDir = path.join(path.dirname(packageJsonPath), '..', '..', 'node_modules');
73
+ dependencyDir = path.join(path.dirname(mainPackageJsonPath), '..', '..', 'node_modules');
74
74
  } else {
75
- dependencyDir = path.join(path.dirname(packageJsonPath), 'node_modules');
75
+ dependencyDir = path.join(path.dirname(mainPackageJsonPath), 'node_modules');
76
76
  }
77
- addAllDependencies(dependencyDir, started, packageJsonPath);
77
+ addAllDependencies(dependencyDir, started, mainPackageJsonPath);
78
78
  });
79
79
  };
80
80
 
@@ -89,6 +89,7 @@ exports.activate = function activate() {
89
89
  function addAllDependencies(dependencyDir, started, packageJsonPath) {
90
90
  addDependenciesFromDir(dependencyDir, () => {
91
91
  if (Object.keys(preliminaryPayload).length <= exports.MAX_DEPENDENCIES) {
92
+ // @ts-ignore: Cannot redeclare exported variable 'currentPayload'
92
93
  exports.currentPayload = preliminaryPayload;
93
94
  logger.debug(`Collection of dependencies took ${Date.now() - started} ms.`);
94
95
  return;
@@ -238,6 +239,7 @@ function limitAndSet(distances = {}) {
238
239
  for (let i = 0; i < keys.length - exports.MAX_DEPENDENCIES; i++) {
239
240
  delete preliminaryPayload[keys[i]];
240
241
  }
242
+ // @ts-ignore: Cannot redeclare exported variable 'currentPayload'
241
243
  exports.currentPayload = preliminaryPayload;
242
244
  }
243
245
 
package/src/gc.js CHANGED
@@ -37,7 +37,8 @@ exports.currentPayload = {
37
37
  majorGcs: 0,
38
38
  incrementalMarkings: 0,
39
39
  weakCallbackProcessing: 0,
40
- gcPause: 0
40
+ gcPause: 0,
41
+ statsSupported: false
41
42
  };
42
43
 
43
44
  exports.activate = function activate() {
package/src/libuv.js CHANGED
@@ -47,5 +47,7 @@ function sense() {
47
47
  stats.statsSupported = true;
48
48
  return stats;
49
49
  }
50
- return {};
50
+ return {
51
+ statsSupported: false
52
+ };
51
53
  }
@@ -11,9 +11,8 @@ const EventEmitter = require('events');
11
11
  const copy = require('recursive-copy');
12
12
  const fs = require('fs');
13
13
  const os = require('os');
14
+ const semver = require('semver');
14
15
  const path = require('path');
15
- const tar = require('tar');
16
- const { fork } = require('child_process');
17
16
  const detectLibc = require('detect-libc');
18
17
 
19
18
  /**
@@ -26,20 +25,9 @@ const detectLibc = require('detect-libc');
26
25
  * @property {string} [loadFrom]
27
26
  */
28
27
 
29
- /** @type {Array.<string>} */
30
- const retryMechanisms = [];
31
- if (
32
- !process.env.INSTANA_COPY_PRECOMPILED_NATIVE_ADDONS ||
33
- process.env.INSTANA_COPY_PRECOMPILED_NATIVE_ADDONS.toLowerCase() !== 'false'
34
- ) {
35
- retryMechanisms.push('copy-precompiled');
36
- }
37
- if (
38
- process.env.INSTANA_REBUILD_NATIVE_ADDONS_ON_DEMAND &&
39
- process.env.INSTANA_REBUILD_NATIVE_ADDONS_ON_DEMAND.toLowerCase() === 'true'
40
- ) {
41
- retryMechanisms.push('rebuild');
42
- }
28
+ const copyPrecompiledDisabled =
29
+ process.env.INSTANA_COPY_PRECOMPILED_NATIVE_ADDONS &&
30
+ process.env.INSTANA_COPY_PRECOMPILED_NATIVE_ADDONS.toLowerCase() === 'false';
43
31
 
44
32
  const platform = os.platform();
45
33
  const arch = process.arch;
@@ -60,18 +48,16 @@ function loadNativeAddOn(opts) {
60
48
  // Give clients a chance to register event listeners on the emitter that we return by attempting to load the module
61
49
  // asynchronously on the next tick.
62
50
  opts.loadFrom = opts.nativeModuleName;
63
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, 0));
51
+ process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter));
64
52
  return loaderEmitter;
65
53
  }
66
54
 
67
55
  /**
68
56
  * @param {InstanaSharedMetricsOptions} opts
69
57
  * @param {EventEmitter} loaderEmitter
70
- * @param {number} retryIndex
71
- * @param {boolean} skipAttempt
72
- * @returns
58
+ * @returns {boolean}
73
59
  */
74
- function loadNativeAddOnInternal(opts, loaderEmitter, retryIndex, skipAttempt) {
60
+ function loadNativeAddOnInternal(opts, loaderEmitter) {
75
61
  try {
76
62
  const { isMainThread } = require('worker_threads');
77
63
  if (!isMainThread) {
@@ -83,21 +69,32 @@ function loadNativeAddOnInternal(opts, loaderEmitter, retryIndex, skipAttempt) {
83
69
  // worker threads are not available, so we know that this is the main thread
84
70
  }
85
71
 
86
- if (skipAttempt) {
87
- // The logic of the previous retry mechanism figured out that it cannot complete successfully, so there is no reason
88
- // to try to require the module again. Skip directly to the next retry.
89
- logger.debug(`Skipping attempt ${retryIndex + 1} to load native add-on ${opts.nativeModuleName}.`);
90
- prepareNextRetry(opts, loaderEmitter, retryIndex);
91
- } else {
92
- logger.debug(`Attempt ${retryIndex + 1} to load native add-on ${opts.nativeModuleName} from ${opts.loadFrom}.`);
93
- try {
94
- // Try to actually require the native add-on module.
95
- const nativeModule = require(opts.loadFrom);
96
- loaderEmitter.emit('loaded', nativeModule);
97
- logger.debug(`Attempt ${retryIndex + 1} to load native add-on ${opts.nativeModuleName} has been successful.`);
98
- } catch (e) {
99
- logger.debug(`Attempt ${retryIndex + 1} to load native add-on ${opts.nativeModuleName} has failed.`, e);
100
- prepareNextRetry(opts, loaderEmitter, retryIndex);
72
+ let nativeModuleHasBeenRequiredSuccessfully = attemptRequire(opts, loaderEmitter, 'directly');
73
+ if (!nativeModuleHasBeenRequiredSuccessfully) {
74
+ if (!copyPrecompiledDisabled) {
75
+ copyPrecompiled(opts, loaderEmitter, success => {
76
+ if (success) {
77
+ // The initial attempt to require the native add-on directly has failed but copying the precompiled add-on
78
+ // binaries has been successful. Try to require the precompiled add-on now.
79
+ nativeModuleHasBeenRequiredSuccessfully = attemptRequire(
80
+ opts,
81
+ loaderEmitter,
82
+ 'after copying precompiled binaries'
83
+ );
84
+ if (!nativeModuleHasBeenRequiredSuccessfully) {
85
+ // Requiring the precompiled add-on has failed after successfully copying them.
86
+ giveUp(opts, loaderEmitter);
87
+ }
88
+ } else {
89
+ // The initial attempt to require the native add-on directly has failed and copying the precompiled add-on
90
+ // binaries has also failed.
91
+ giveUp(opts, loaderEmitter);
92
+ }
93
+ });
94
+ } else {
95
+ // The initial attempt to require the native add-on directly has failed and copying the precompiled add-on
96
+ // binaries has been explicitly disabled via INSTANA_COPY_PRECOMPILED_NATIVE_ADDONS=false.
97
+ giveUp(opts, loaderEmitter);
101
98
  }
102
99
  }
103
100
  }
@@ -105,49 +102,50 @@ function loadNativeAddOnInternal(opts, loaderEmitter, retryIndex, skipAttempt) {
105
102
  /**
106
103
  * @param {InstanaSharedMetricsOptions} opts
107
104
  * @param {EventEmitter} loaderEmitter
108
- * @param {number} retryIndex
105
+ * @param {string} mechanism
109
106
  */
110
- function prepareNextRetry(opts, loaderEmitter, retryIndex) {
111
- // The first pre-condition for all retry mechanisms is that we can find the path to the native add-on that can not be
112
- // required.
113
- if (!opts.nativeModulePath || !opts.nativeModuleParentPath) {
114
- findNativeModulePath(opts);
115
- if (!opts.nativeModulePath || !opts.nativeModuleParentPath) {
116
- logger.warn(opts.message + ' (No retry attempted.)');
117
- loaderEmitter.emit('failed');
118
- return;
119
- }
107
+ function attemptRequire(opts, loaderEmitter, mechanism) {
108
+ try {
109
+ // Try to actually require the native add-on module.
110
+ const nativeModule = require(opts.loadFrom);
111
+ loaderEmitter.emit('loaded', nativeModule);
112
+ logger.debug(`Attempt to load native add-on ${opts.nativeModuleName} ${mechanism} has been successful.`);
113
+ return true;
114
+ } catch (e) {
115
+ logger.debug(`Attempt to load native add-on ${opts.nativeModuleName} ${mechanism} has failed.`, e);
116
+ return false;
120
117
  }
118
+ }
121
119
 
122
- const nextRetryMechanism = retryMechanisms[retryIndex];
123
- if (!nextRetryMechanism) {
124
- // We have exhausted all possible mechanisms to cope with the failure to load the native add-on.
125
- logger.warn(opts.message);
126
- loaderEmitter.emit('failed');
127
- } else if (nextRetryMechanism === 'copy-precompiled') {
128
- copyPrecompiled(opts, loaderEmitter, retryIndex);
129
- } else if (nextRetryMechanism === 'rebuild') {
130
- rebuildOnDemand(opts, loaderEmitter, retryIndex);
131
- } else {
132
- logger.error(
133
- `Unknown retry mechanism for loading the native module ${opts.nativeModuleName}: ${nextRetryMechanism}.`
134
- );
135
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
136
- }
120
+ /**
121
+ * @param {InstanaSharedMetricsOptions} opts
122
+ * @param {EventEmitter} loaderEmitter
123
+ */
124
+ function giveUp(opts, loaderEmitter) {
125
+ logger.warn(opts.message);
126
+ loaderEmitter.emit('failed');
137
127
  }
138
128
 
139
129
  /**
140
130
  * @param {InstanaSharedMetricsOptions} opts
141
131
  * @param {EventEmitter} loaderEmitter
142
- * @param {number} retryIndex
132
+ * @param {(success: boolean) => void} callback
143
133
  */
144
- function copyPrecompiled(opts, loaderEmitter, retryIndex) {
134
+ function copyPrecompiled(opts, loaderEmitter, callback) {
145
135
  logger.debug(`Trying to copy precompiled version of ${opts.nativeModuleName} for Node.js ${process.version}.`);
146
136
 
137
+ if (!opts.nativeModulePath || !opts.nativeModuleParentPath) {
138
+ if (!findNativeModulePath(opts)) {
139
+ logger.warn(`Unable to find or construct a path for native add-on ${opts.nativeModuleName}.`);
140
+ process.nextTick(callback.bind(false));
141
+ return;
142
+ }
143
+ }
144
+
147
145
  const abi = process.versions.modules;
148
146
  if (!abi) {
149
147
  logger.warn(`Could not determine ABI version for Node.js version ${process.version}.`);
150
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
148
+ process.nextTick(callback.bind(false));
151
149
  return;
152
150
  }
153
151
 
@@ -163,19 +161,30 @@ function copyPrecompiled(opts, loaderEmitter, retryIndex) {
163
161
  logger.info(
164
162
  `A precompiled version for ${opts.nativeModuleName} is not available ${label} (at ${precompiledTarGzPath}).`
165
163
  );
166
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
164
+ callback(false);
167
165
  return;
168
- // Note: We could combine copying and recompiling for cases where we do not have a precompiled version but
169
- // node-gyp is available. That is, copy the precompiled package (from an arbitrary architecture/ABI version), then
170
- // rebuild that.
171
166
  } else if (statsErr) {
172
167
  logger.warn(`Looking for a precompiled version for ${opts.nativeModuleName} ${label} failed.`, statsErr);
173
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
168
+ callback(false);
174
169
  return;
175
170
  }
176
171
 
177
172
  logger.info(`Found a precompiled version for ${opts.nativeModuleName} ${label}, unpacking.`);
178
173
 
174
+ /**
175
+ * tar@6 has dropped support for Node < 10
176
+ * It might work to require tar@6 or to execute commands with tar@6 and Node < 10,
177
+ * but we don't want to risk that a customers application fails - especially if tar@6 adds
178
+ * breaking changes. We decided to disallow this feature.
179
+ */
180
+ if (semver.lt(process.version, '10.0.0')) {
181
+ logger.info(`Skipped copying precompiled version for ${opts.nativeModuleName} ${label} with Node < 10.`);
182
+ callback(false);
183
+ return;
184
+ }
185
+
186
+ const tar = require('tar');
187
+
179
188
  tar
180
189
  .x({
181
190
  cwd: os.tmpdir(),
@@ -197,7 +206,7 @@ function copyPrecompiled(opts, loaderEmitter, retryIndex) {
197
206
  cpErr => {
198
207
  if (cpErr) {
199
208
  logger.warn(`Copying the precompiled build for ${opts.nativeModuleName} ${label} failed.`, cpErr);
200
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
209
+ callback(false);
201
210
  return;
202
211
  }
203
212
 
@@ -205,86 +214,25 @@ function copyPrecompiled(opts, loaderEmitter, retryIndex) {
205
214
  // dependency should work.
206
215
  //
207
216
  // However, we must not use any of the paths from which Node.js has tried to load the module before (that
208
- // is, node_modules/${opts.nativeModuleName}). Node.js has module loading infrastructure
217
+ // is, node_modules/${opts.nativeModuleName}). Node.js' module loading infrastructure
209
218
  // (lib/internal/modules/cjs/loader.js and lib/internal/modules/package_json_reader.js) have built-in
210
219
  // caching on multiple levels (for example, package.json locations and package.json contents). If Node.js
211
- // has tried unsuccessfully to load a module or read a package.json from a particular path, it will remember
212
- // and not try to load anything from that path again (a `false` will be put into the cache for that cache
213
- // key). Instead, we force a new path, by adding precompiled to the module path and use the absolute path to
214
- // the module to load it.
220
+ // has tried unsuccessfully to load a module or read a package.json from a particular path,
221
+ // it will remember and not try to load anything from that path again (a `false` will be
222
+ // put into the cache for that cache key). Instead, we force a new path, by adding precompiled
223
+ // to the module path and use the absolute path to the module to load it.
215
224
  opts.loadFrom = targetDir;
216
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex));
225
+ callback(true);
217
226
  }
218
227
  );
219
228
  })
220
229
  .catch(tarErr => {
221
230
  logger.warn(`Unpacking the precompiled build for ${opts.nativeModuleName} ${label} failed.`, tarErr);
222
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
231
+ callback(false);
223
232
  });
224
233
  });
225
234
  }
226
235
 
227
- /**
228
- * This is mainly for the scenario where @instana/collector and its dependencies has been provided by an external
229
- * mechanism (like copying a bundled version contained in the Instana agent package) without running an npm install on
230
- * the target system. Native addons are present, but might have been build for a different operating system/Node ABI,
231
- * libc familiy, ...). Thus, they need to be rebuilt.
232
- *
233
- * @param {InstanaSharedMetricsOptions} opts
234
- * @param {EventEmitter} loaderEmitter
235
- * @param {number} retryIndex
236
- */
237
- function rebuildOnDemand(opts, loaderEmitter, retryIndex) {
238
- /** @type {string} */
239
- let nodeGypExecutable;
240
- try {
241
- const nodeGypPath = require.resolve('node-gyp');
242
- if (!nodeGypPath) {
243
- logger.warn(
244
- // eslint-disable-next-line max-len
245
- `Could not find node-gyp (require.resolve didn't return anything) to rebuild ${opts.nativeModuleName} on demand.`
246
- );
247
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
248
- return;
249
- }
250
- nodeGypExecutable = path.join(nodeGypPath, '..', '..', 'bin', 'node-gyp.js');
251
- } catch (e) {
252
- logger.warn(`Could not load node-gyp to rebuild ${opts.nativeModuleName} on demand.`, e);
253
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
254
- return;
255
- }
256
-
257
- logger.info(`Rebuilding ${opts.nativeModulePath} via ${nodeGypExecutable}.`);
258
- const nodeGyp = fork(nodeGypExecutable, ['rebuild'], {
259
- cwd: opts.nativeModulePath
260
- });
261
- nodeGyp.on('error', err => {
262
- logger.warn(
263
- // eslint-disable-next-line max-len
264
- `Attempt to rebuild ${opts.nativeModulePath} via ${nodeGypExecutable} has failed with an error.`,
265
- err
266
- );
267
- });
268
- nodeGyp.on('close', code => {
269
- if (code === 0) {
270
- logger.info(
271
- // eslint-disable-next-line max-len
272
- `Attempt to rebuild ${opts.nativeModulePath} via ${nodeGypExecutable} has finished, will try to load the module again.`
273
- );
274
- // In contrast to copyPrecompiled we do not need to force a different module path here, since in this scenario the
275
- // package contents (including the package.json) was present in the node_modules folder, it was only the binary
276
- // that didn't match the platform/ABI version.
277
- opts.loadFrom = opts.nativeModuleName;
278
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex));
279
- } else {
280
- logger.warn(
281
- `Attempt to rebuild ${opts.nativeModulePath} via ${nodeGypExecutable} has failed with exit code ${code}.`
282
- );
283
- process.nextTick(loadNativeAddOnInternal.bind(null, opts, loaderEmitter, ++retryIndex, true));
284
- }
285
- });
286
- }
287
-
288
236
  /**
289
237
  * @param {InstanaSharedMetricsOptions} opts
290
238
  */
@@ -297,24 +245,24 @@ function findNativeModulePath(opts) {
297
245
  `Could not find location for ${opts.nativeModuleName} (require.resolve didn't return anything). ` +
298
246
  'Will create a path for it.'
299
247
  );
300
- createNativeModulePath(opts);
301
- return;
248
+ return createNativeModulePath(opts);
302
249
  }
303
250
  // We found a path to the module in node_modules, that means the directory exist (and we will reuse it) but the
304
251
  // module installation is incomplete and it could not be loaded earlier (otherwise we wouldn't have gotten here).
305
252
  const idx = nativeModulePath.lastIndexOf('node_modules');
306
253
  if (idx < 0) {
307
254
  logger.warn(`Could not find node_modules substring in ${nativeModulePath}.`);
308
- return;
255
+ return false;
309
256
  }
310
257
  opts.nativeModulePath = nativeModulePath.substring(
311
258
  0,
312
259
  idx + 'node_modules'.length + opts.nativeModuleName.length + 2
313
260
  );
314
261
  opts.nativeModuleParentPath = path.join(opts.nativeModulePath, '..');
262
+ return true;
315
263
  } catch (e) {
316
264
  logger.debug(`Could not find location for ${opts.nativeModuleName}. Will create a path for it.`, e);
317
- createNativeModulePath(opts);
265
+ return createNativeModulePath(opts);
318
266
  }
319
267
  }
320
268
 
@@ -332,7 +280,7 @@ function createNativeModulePath(opts) {
332
280
  logger.warn(
333
281
  `Could not find node_modules substring in ${selfPath}. Will give up loading ${opts.nativeModuleName}.`
334
282
  );
335
- return;
283
+ return false;
336
284
  }
337
285
 
338
286
  // cut off everything after module path
@@ -343,6 +291,7 @@ function createNativeModulePath(opts) {
343
291
  // we need to go up two directory levels.
344
292
  opts.nativeModuleParentPath = loadNativeAddOn.selfNodeModulesPath;
345
293
  opts.nativeModulePath = path.join(loadNativeAddOn.selfNodeModulesPath, opts.nativeModuleName);
294
+ return true;
346
295
  }
347
296
 
348
297
  loadNativeAddOn.setLogger = setLogger;