Spaces:
Runtime error
Runtime error
| ; | |
| 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 |