You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
3.7 KiB
JavaScript
81 lines
3.7 KiB
JavaScript
11 months ago
|
"use strict";
|
||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||
|
exports.MongocryptdManager = void 0;
|
||
|
const error_1 = require("../error");
|
||
|
/**
|
||
|
* @internal
|
||
|
* An internal class that handles spawning a mongocryptd.
|
||
|
*/
|
||
|
class MongocryptdManager {
|
||
|
constructor(extraOptions = {}) {
|
||
|
this.uri =
|
||
|
typeof extraOptions.mongocryptdURI === 'string' && extraOptions.mongocryptdURI.length > 0
|
||
|
? extraOptions.mongocryptdURI
|
||
|
: MongocryptdManager.DEFAULT_MONGOCRYPTD_URI;
|
||
|
this.bypassSpawn = !!extraOptions.mongocryptdBypassSpawn;
|
||
|
this.spawnPath = extraOptions.mongocryptdSpawnPath || '';
|
||
|
this.spawnArgs = [];
|
||
|
if (Array.isArray(extraOptions.mongocryptdSpawnArgs)) {
|
||
|
this.spawnArgs = this.spawnArgs.concat(extraOptions.mongocryptdSpawnArgs);
|
||
|
}
|
||
|
if (this.spawnArgs
|
||
|
.filter(arg => typeof arg === 'string')
|
||
|
.every(arg => arg.indexOf('--idleShutdownTimeoutSecs') < 0)) {
|
||
|
this.spawnArgs.push('--idleShutdownTimeoutSecs', '60');
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Will check to see if a mongocryptd is up. If it is not up, it will attempt
|
||
|
* to spawn a mongocryptd in a detached process, and then wait for it to be up.
|
||
|
*/
|
||
|
async spawn() {
|
||
|
const cmdName = this.spawnPath || 'mongocryptd';
|
||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||
|
const { spawn } = require('child_process');
|
||
|
// Spawned with stdio: ignore and detached: true
|
||
|
// to ensure child can outlive parent.
|
||
|
this._child = spawn(cmdName, this.spawnArgs, {
|
||
|
stdio: 'ignore',
|
||
|
detached: true
|
||
|
});
|
||
|
this._child.on('error', () => {
|
||
|
// From the FLE spec:
|
||
|
// "The stdout and stderr of the spawned process MUST not be exposed in the driver
|
||
|
// (e.g. redirect to /dev/null). Users can pass the argument --logpath to
|
||
|
// extraOptions.mongocryptdSpawnArgs if they need to inspect mongocryptd logs.
|
||
|
// If spawning is necessary, the driver MUST spawn mongocryptd whenever server
|
||
|
// selection on the MongoClient to mongocryptd fails. If the MongoClient fails to
|
||
|
// connect after spawning, the server selection error is propagated to the user."
|
||
|
// The AutoEncrypter and MongoCryptdManager should work together to spawn
|
||
|
// mongocryptd whenever necessary. Additionally, the `mongocryptd` intentionally
|
||
|
// shuts down after 60s and gets respawned when necessary. We rely on server
|
||
|
// selection timeouts when connecting to the `mongocryptd` to inform users that something
|
||
|
// has been configured incorrectly. For those reasons, we suppress stderr from
|
||
|
// the `mongocryptd` process and immediately unref the process.
|
||
|
});
|
||
|
// unref child to remove handle from event loop
|
||
|
this._child.unref();
|
||
|
}
|
||
|
/**
|
||
|
* @returns the result of `fn` or rejects with an error.
|
||
|
*/
|
||
|
async withRespawn(fn) {
|
||
|
try {
|
||
|
const result = await fn();
|
||
|
return result;
|
||
|
}
|
||
|
catch (err) {
|
||
|
// If we are not bypassing spawning, then we should retry once on a MongoTimeoutError (server selection error)
|
||
|
const shouldSpawn = err instanceof error_1.MongoNetworkTimeoutError && !this.bypassSpawn;
|
||
|
if (!shouldSpawn) {
|
||
|
throw err;
|
||
|
}
|
||
|
}
|
||
|
await this.spawn();
|
||
|
const result = await fn();
|
||
|
return result;
|
||
|
}
|
||
|
}
|
||
|
MongocryptdManager.DEFAULT_MONGOCRYPTD_URI = 'mongodb://localhost:27020';
|
||
|
exports.MongocryptdManager = MongocryptdManager;
|
||
|
//# sourceMappingURL=mongocryptd_manager.js.map
|