Skip to content

Commit

Permalink
feat: Try to restart once mongod on shutdown
Browse files Browse the repository at this point in the history
`mongodb-prebuilt` on "addr in use" error returns "Mongod shutting down"
error. So we can not be exactly sure that problem was in busy port.
That's why we try only one time more to start mongo.
  • Loading branch information
nodkz committed May 19, 2017
1 parent f58c2b1 commit d74da82
Showing 1 changed file with 57 additions and 46 deletions.
103 changes: 57 additions & 46 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,46 +46,29 @@ export default class MongoDBMemoryServer {
}
}

debug(msg: string) {
if (this.opts.debug) {
console.log(msg);
}
}

async start(): Promise<boolean> {
if (this.runningInstance) {
throw new Error(
'MongoDB instance already in status startup/running/error. Use opts.debug = true for more info.'
);
}

this.runningInstance = Promise.resolve().then(async () => {
const data = {};
let tmpDir;

data.port = await getport(this.opts.port);
data.uri = await generateConnectionString(data.port);
data.storageEngine = this.opts.storageEngine || 'ephemeralForTest';
if (this.opts.dbPath) {
data.dbPath = this.opts.dbPath;
} else {
tmpDir = tmp.dirSync({ prefix: 'mongo-mem-', unsafeCleanup: true });
data.dbPath = tmpDir.name;
}

if (this.opts.debug) {
console.log(`Starting MongoDB instance with following options: ${JSON.stringify(data)}`);
}

const mongodCli = new MongodHelper([
'--port',
data.port,
'--storageEngine',
data.storageEngine,
'--dbpath',
data.dbPath,
'--noauth',
]);

mongodCli.debug.enabled = this.opts.debug;

// Download if not exists mongo binaries in ~/.mongodb-prebuilt
// After that startup MongoDB instance
await mongodCli.run().catch(err => {
this.runningInstance = this._startUpInstance()
.catch(err => {
if (err.message === 'Mongod shutting down' || err === 'Mongod shutting down') {
this.debug(`Mongodb does not started. Trying to start on another port one more time...`);
this.opts.port = null;
return this._startUpInstance();
}
throw err;
})
.catch(err => {
if (!this.opts.debug) {
throw new Error(
`${err.message}\n\nUse debug option for more info: new MongoMemoryServer({ debug: true })`
Expand All @@ -94,32 +77,60 @@ export default class MongoDBMemoryServer {
throw err;
});

data.mongodCli = mongodCli;
data.tmpDir = tmpDir;
return this.runningInstance.then(() => true);
}

return data;
});
async _startUpInstance(): Promise<MongoInstanceDataT> {
const data = {};
let tmpDir;

data.port = await getport(this.opts.port);
data.uri = await generateConnectionString(data.port);
data.storageEngine = this.opts.storageEngine || 'ephemeralForTest';
if (this.opts.dbPath) {
data.dbPath = this.opts.dbPath;
} else {
tmpDir = tmp.dirSync({ prefix: 'mongo-mem-', unsafeCleanup: true });
data.dbPath = tmpDir.name;
}

return this.runningInstance.then(() => true);
this.debug(`Starting MongoDB instance with following options: ${JSON.stringify(data)}`);

const mongodCli = new MongodHelper([
'--port',
data.port,
'--storageEngine',
data.storageEngine,
'--dbpath',
data.dbPath,
'--noauth',
]);

mongodCli.debug.enabled = this.opts.debug;

// Download if not exists mongo binaries in ~/.mongodb-prebuilt
// After that startup MongoDB instance
await mongodCli.run();

data.mongodCli = mongodCli;
data.tmpDir = tmpDir;

return data;
}

async stop(): Promise<boolean> {
const { mongodCli, port, tmpDir } = await this.getInstanceData();

if (mongodCli && mongodCli.mongoBin.childProcess) {
// .mongoBin.childProcess.connected
if (this.opts.debug) {
console.log(
`Shutdown MongoDB server on port ${port} with pid ${mongodCli.mongoBin.childProcess.pid}`
);
}
this.debug(
`Shutdown MongoDB server on port ${port} with pid ${mongodCli.mongoBin.childProcess.pid}`
);
mongodCli.mongoBin.childProcess.kill();
}

if (tmpDir) {
if (this.opts.debug) {
console.log(`Removing tmpDir ${tmpDir.name}`);
}
this.debug(`Removing tmpDir ${tmpDir.name}`);
tmpDir.removeCallback();
}

Expand Down

0 comments on commit d74da82

Please sign in to comment.