使用 `connect-mongo` 和带有 MongoDB Atlas 的 Mongoose 的计时问题
Timing issue using `connect-mongo` and Mongoose with MongoDB Atlas
我正在使用 connect-mongo for my ExpressJS Session Store and Mongoose 进行我的数据库连接,我将称之为时间问题。这是我的代码:
dbservice.js
const mongoose = require('mongoose');
const debug = require('debug')('app:core:db:service');
const chalk = require('chalk');
const config = require('config');
const mongoDbUrl = config.mongodb_url;
const mongoDbOptions = {
useUnifiedTopology: true,
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
};
(async () => {
try {
await mongoose.connect(mongoDbUrl, mongoDbOptions);
debug(`Connected to ${chalk.green('MongoDB')}`);
} catch (err) {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
}
})();
const db = mongoose.connection;
db.on('error', (err) => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
});
// For nodemon restarts
process.once('SIGUSR2', () => {
const msg = 'Nodemon Restart';
db.close()
.then(() => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`closed`)}: ${msg}`);
process.kill(process.pid, 'SIGUSR2');
})
.catch((err) => {
debug(err);
});
});
const dbClient = db.getClient();
module.exports = dbClient;
app.js
const dbClient = require('dbService');
// Using Express Session with Google Cloud Datastore to securly store session/cookie information
app.use(
session({
// Using MongoDB as session store
store: MongoStore.create({
client: dbClient, // Use Mongoose for DB Conection
ttl: 1800000, // Ages session out at 30 minutes
autoRemove: 'native', // Uses MongoDB's native Time to Live (TTL) to expire and remove records
},
}),
}),
);
此代码在使用 MongoDB 的本地网络实例时效果很好,因为连接到 MongoDB 的延迟非常小,因此它可以正常工作。但是,当使用 MongoDB Atlas 时,连接会有一到两秒的延迟。所以,我怀疑(我认为很棒的)我在 dbservice.js
中的代码行 const dbClient = db.getClient()
失败了 connect-mongo
抛出错误:
(node:1148) UnhandledPromiseRejectionWarning: MongoError: MongoClient must be connected before calling MongoClient.prototype.db` because Mongoose is not connected.
作为新手,我一直在努力尝试解决这个问题。我试图找到一种方法来使用 mongoose.connection.readyState
等待它 returned a 1
连接但失败了。
我的问题是:有没有更好的方法让我 return dbClient
正确等待 Mongoose 连接到 MongoDB?非常感谢任何帮助。
您没有从 dbservice.js
中返回 Promise
(async () => {})()
对异步代码没有意义
您的代码应该是这样的
const getDbClient = async () => {
try {
await mongoose.connect(mongoDbUrl, mongoDbOptions);
debug(`Connected to ${chalk.green('MongoDB')}`);
const db = mongoose.connection;
return db.getClient()
} catch (err) {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
}
}
function async start() {
const client = await getDbClient()
// Using Express Session with Google Cloud Datastore to securly store session/cookie information
app.use(
session({
// Using MongoDB as session store
store: MongoStore.create({
client: client, // Use Mongoose for DB Conection
ttl: 1800000, // Ages session out at 30 minutes
autoRemove: 'native', // Uses MongoDB's native Time to Live (TTL) to expire and remove records
},
}),
}),
);
// Here is server startup code.... app.listen etc.
}
start.then(() => console.log('started'))
根据 Nikita Mazur 的回复,我将 dbservices.js
修改为以下内容:
const mongoose = require('mongoose');
const debug = require('debug')('app:core:db:service');
const chalk = require('chalk');
const { mongoDbUrl } = require('../config/config');
const mongoDbOptions = {
useUnifiedTopology: true,
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
};
async function dbConnection() {
try {
await mongoose.connect(mongoDbUrl, mongoDbOptions);
debug(`Connected to ${chalk.green('MongoDB')}`);
} catch (err) {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
}
return mongoose.connection.getClient();
}
const db = mongoose.connection;
db.on('error', (err) => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
});
// For nodemon restarts
process.once('SIGUSR2', () => {
const msg = 'Nodemon Restart';
db.close()
.then(() => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`closed`)}: ${msg}`);
process.kill(process.pid, 'SIGUSR2');
})
.catch((err) => {
debug(err);
});
});
module.exports = dbConnection();
我正在使用 connect-mongo for my ExpressJS Session Store and Mongoose 进行我的数据库连接,我将称之为时间问题。这是我的代码:
dbservice.js
const mongoose = require('mongoose');
const debug = require('debug')('app:core:db:service');
const chalk = require('chalk');
const config = require('config');
const mongoDbUrl = config.mongodb_url;
const mongoDbOptions = {
useUnifiedTopology: true,
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
};
(async () => {
try {
await mongoose.connect(mongoDbUrl, mongoDbOptions);
debug(`Connected to ${chalk.green('MongoDB')}`);
} catch (err) {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
}
})();
const db = mongoose.connection;
db.on('error', (err) => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
});
// For nodemon restarts
process.once('SIGUSR2', () => {
const msg = 'Nodemon Restart';
db.close()
.then(() => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`closed`)}: ${msg}`);
process.kill(process.pid, 'SIGUSR2');
})
.catch((err) => {
debug(err);
});
});
const dbClient = db.getClient();
module.exports = dbClient;
app.js
const dbClient = require('dbService');
// Using Express Session with Google Cloud Datastore to securly store session/cookie information
app.use(
session({
// Using MongoDB as session store
store: MongoStore.create({
client: dbClient, // Use Mongoose for DB Conection
ttl: 1800000, // Ages session out at 30 minutes
autoRemove: 'native', // Uses MongoDB's native Time to Live (TTL) to expire and remove records
},
}),
}),
);
此代码在使用 MongoDB 的本地网络实例时效果很好,因为连接到 MongoDB 的延迟非常小,因此它可以正常工作。但是,当使用 MongoDB Atlas 时,连接会有一到两秒的延迟。所以,我怀疑(我认为很棒的)我在 dbservice.js
中的代码行 const dbClient = db.getClient()
失败了 connect-mongo
抛出错误:
(node:1148) UnhandledPromiseRejectionWarning: MongoError: MongoClient must be connected before calling MongoClient.prototype.db` because Mongoose is not connected.
作为新手,我一直在努力尝试解决这个问题。我试图找到一种方法来使用 mongoose.connection.readyState
等待它 returned a 1
连接但失败了。
我的问题是:有没有更好的方法让我 return dbClient
正确等待 Mongoose 连接到 MongoDB?非常感谢任何帮助。
您没有从 dbservice.js
中返回 Promise(async () => {})()
对异步代码没有意义
您的代码应该是这样的
const getDbClient = async () => {
try {
await mongoose.connect(mongoDbUrl, mongoDbOptions);
debug(`Connected to ${chalk.green('MongoDB')}`);
const db = mongoose.connection;
return db.getClient()
} catch (err) {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
}
}
function async start() {
const client = await getDbClient()
// Using Express Session with Google Cloud Datastore to securly store session/cookie information
app.use(
session({
// Using MongoDB as session store
store: MongoStore.create({
client: client, // Use Mongoose for DB Conection
ttl: 1800000, // Ages session out at 30 minutes
autoRemove: 'native', // Uses MongoDB's native Time to Live (TTL) to expire and remove records
},
}),
}),
);
// Here is server startup code.... app.listen etc.
}
start.then(() => console.log('started'))
根据 Nikita Mazur 的回复,我将 dbservices.js
修改为以下内容:
const mongoose = require('mongoose');
const debug = require('debug')('app:core:db:service');
const chalk = require('chalk');
const { mongoDbUrl } = require('../config/config');
const mongoDbOptions = {
useUnifiedTopology: true,
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
};
async function dbConnection() {
try {
await mongoose.connect(mongoDbUrl, mongoDbOptions);
debug(`Connected to ${chalk.green('MongoDB')}`);
} catch (err) {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
}
return mongoose.connection.getClient();
}
const db = mongoose.connection;
db.on('error', (err) => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`error`)}: ${err}`);
});
// For nodemon restarts
process.once('SIGUSR2', () => {
const msg = 'Nodemon Restart';
db.close()
.then(() => {
debug(`${chalk.green('MongoDB')} connection ${chalk.red(`closed`)}: ${msg}`);
process.kill(process.pid, 'SIGUSR2');
})
.catch((err) => {
debug(err);
});
});
module.exports = dbConnection();