@instana/shared-metrics 1.132.2 → 1.136.0
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/package.json +6 -6
- package/src/dependencies.js +9 -7
- package/src/util/nativeModuleRetry.js +74 -139
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instana/shared-metrics",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.136.0",
|
|
4
4
|
"description": "Internal metrics plug-in package for Node.js monitoring with Instana",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bastian Krol",
|
|
@@ -59,13 +59,14 @@
|
|
|
59
59
|
},
|
|
60
60
|
"license": "MIT",
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@instana/core": "1.
|
|
62
|
+
"@instana/core": "1.136.0",
|
|
63
63
|
"detect-libc": "^1.0.3",
|
|
64
64
|
"event-loop-lag": "^1.4.0",
|
|
65
65
|
"recursive-copy": "^2.0.13",
|
|
66
|
-
"tar": "^5.0.
|
|
66
|
+
"tar": "^5.0.11"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
+
"@types/tar": "^4.0.5",
|
|
69
70
|
"eslint": "^7.30.0",
|
|
70
71
|
"eslint-config-airbnb-base": "^14.2.1",
|
|
71
72
|
"eslint-plugin-import": "^2.23.4",
|
|
@@ -75,8 +76,7 @@
|
|
|
75
76
|
},
|
|
76
77
|
"optionalDependencies": {
|
|
77
78
|
"event-loop-stats": "1.3.0",
|
|
78
|
-
"gcstats.js": "1.0.0"
|
|
79
|
-
"node-gyp": "^7.1.2"
|
|
79
|
+
"gcstats.js": "1.0.0"
|
|
80
80
|
},
|
|
81
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "2a2aaf4aa675a10ba0534c50e9bd2c34ab104d78"
|
|
82
82
|
}
|
package/src/dependencies.js
CHANGED
|
@@ -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,
|
|
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 (!
|
|
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 (!
|
|
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(
|
|
73
|
+
dependencyDir = path.join(path.dirname(mainPackageJsonPath), '..', '..', 'node_modules');
|
|
74
74
|
} else {
|
|
75
|
-
dependencyDir = path.join(path.dirname(
|
|
75
|
+
dependencyDir = path.join(path.dirname(mainPackageJsonPath), 'node_modules');
|
|
76
76
|
}
|
|
77
|
-
addAllDependencies(dependencyDir, started,
|
|
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
|
|
|
@@ -13,7 +13,6 @@ const fs = require('fs');
|
|
|
13
13
|
const os = require('os');
|
|
14
14
|
const path = require('path');
|
|
15
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
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
|
-
* @
|
|
71
|
-
* @param {boolean} skipAttempt
|
|
72
|
-
* @returns
|
|
58
|
+
* @returns {boolean}
|
|
73
59
|
*/
|
|
74
|
-
function loadNativeAddOnInternal(opts, loaderEmitter
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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 {
|
|
105
|
+
* @param {string} mechanism
|
|
109
106
|
*/
|
|
110
|
-
function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
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 {
|
|
132
|
+
* @param {(success: boolean) => void} callback
|
|
143
133
|
*/
|
|
144
|
-
function copyPrecompiled(opts, loaderEmitter,
|
|
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(
|
|
148
|
+
process.nextTick(callback.bind(false));
|
|
151
149
|
return;
|
|
152
150
|
}
|
|
153
151
|
|
|
@@ -163,14 +161,11 @@ 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
|
-
|
|
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
|
-
|
|
168
|
+
callback(false);
|
|
174
169
|
return;
|
|
175
170
|
}
|
|
176
171
|
|
|
@@ -197,7 +192,7 @@ function copyPrecompiled(opts, loaderEmitter, retryIndex) {
|
|
|
197
192
|
cpErr => {
|
|
198
193
|
if (cpErr) {
|
|
199
194
|
logger.warn(`Copying the precompiled build for ${opts.nativeModuleName} ${label} failed.`, cpErr);
|
|
200
|
-
|
|
195
|
+
callback(false);
|
|
201
196
|
return;
|
|
202
197
|
}
|
|
203
198
|
|
|
@@ -205,7 +200,7 @@ function copyPrecompiled(opts, loaderEmitter, retryIndex) {
|
|
|
205
200
|
// dependency should work.
|
|
206
201
|
//
|
|
207
202
|
// 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
|
|
203
|
+
// is, node_modules/${opts.nativeModuleName}). Node.js' module loading infrastructure
|
|
209
204
|
// (lib/internal/modules/cjs/loader.js and lib/internal/modules/package_json_reader.js) have built-in
|
|
210
205
|
// caching on multiple levels (for example, package.json locations and package.json contents). If Node.js
|
|
211
206
|
// has tried unsuccessfully to load a module or read a package.json from a particular path, it will remember
|
|
@@ -213,78 +208,17 @@ function copyPrecompiled(opts, loaderEmitter, retryIndex) {
|
|
|
213
208
|
// key). Instead, we force a new path, by adding precompiled to the module path and use the absolute path to
|
|
214
209
|
// the module to load it.
|
|
215
210
|
opts.loadFrom = targetDir;
|
|
216
|
-
|
|
211
|
+
callback(true);
|
|
217
212
|
}
|
|
218
213
|
);
|
|
219
214
|
})
|
|
220
215
|
.catch(tarErr => {
|
|
221
216
|
logger.warn(`Unpacking the precompiled build for ${opts.nativeModuleName} ${label} failed.`, tarErr);
|
|
222
|
-
|
|
217
|
+
callback(false);
|
|
223
218
|
});
|
|
224
219
|
});
|
|
225
220
|
}
|
|
226
221
|
|
|
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
222
|
/**
|
|
289
223
|
* @param {InstanaSharedMetricsOptions} opts
|
|
290
224
|
*/
|
|
@@ -297,24 +231,24 @@ function findNativeModulePath(opts) {
|
|
|
297
231
|
`Could not find location for ${opts.nativeModuleName} (require.resolve didn't return anything). ` +
|
|
298
232
|
'Will create a path for it.'
|
|
299
233
|
);
|
|
300
|
-
createNativeModulePath(opts);
|
|
301
|
-
return;
|
|
234
|
+
return createNativeModulePath(opts);
|
|
302
235
|
}
|
|
303
236
|
// We found a path to the module in node_modules, that means the directory exist (and we will reuse it) but the
|
|
304
237
|
// module installation is incomplete and it could not be loaded earlier (otherwise we wouldn't have gotten here).
|
|
305
238
|
const idx = nativeModulePath.lastIndexOf('node_modules');
|
|
306
239
|
if (idx < 0) {
|
|
307
240
|
logger.warn(`Could not find node_modules substring in ${nativeModulePath}.`);
|
|
308
|
-
return;
|
|
241
|
+
return false;
|
|
309
242
|
}
|
|
310
243
|
opts.nativeModulePath = nativeModulePath.substring(
|
|
311
244
|
0,
|
|
312
245
|
idx + 'node_modules'.length + opts.nativeModuleName.length + 2
|
|
313
246
|
);
|
|
314
247
|
opts.nativeModuleParentPath = path.join(opts.nativeModulePath, '..');
|
|
248
|
+
return true;
|
|
315
249
|
} catch (e) {
|
|
316
250
|
logger.debug(`Could not find location for ${opts.nativeModuleName}. Will create a path for it.`, e);
|
|
317
|
-
createNativeModulePath(opts);
|
|
251
|
+
return createNativeModulePath(opts);
|
|
318
252
|
}
|
|
319
253
|
}
|
|
320
254
|
|
|
@@ -332,7 +266,7 @@ function createNativeModulePath(opts) {
|
|
|
332
266
|
logger.warn(
|
|
333
267
|
`Could not find node_modules substring in ${selfPath}. Will give up loading ${opts.nativeModuleName}.`
|
|
334
268
|
);
|
|
335
|
-
return;
|
|
269
|
+
return false;
|
|
336
270
|
}
|
|
337
271
|
|
|
338
272
|
// cut off everything after module path
|
|
@@ -343,6 +277,7 @@ function createNativeModulePath(opts) {
|
|
|
343
277
|
// we need to go up two directory levels.
|
|
344
278
|
opts.nativeModuleParentPath = loadNativeAddOn.selfNodeModulesPath;
|
|
345
279
|
opts.nativeModulePath = path.join(loadNativeAddOn.selfNodeModulesPath, opts.nativeModuleName);
|
|
280
|
+
return true;
|
|
346
281
|
}
|
|
347
282
|
|
|
348
283
|
loadNativeAddOn.setLogger = setLogger;
|