#node.js #mongoose #amazon-elastic-beanstalk #dialogflow-es #sigint
#node.js #мангуст #amazon-elastic-beanstalk #диалоговые потоки #sigint
Вопрос:
Я развертываю приложение Node JS Express для веб-интерфейса Dialogflow на AWS Elastic Beanstalk. Приложение использует mongoose для сохранения данных в MongoDB. Есть четыре события подключения (подключено / отключено / ошибка / завершение процесса). В журнале моей консоли выдается следующее предупреждение: MaxListenersExceededWarning: обнаружена возможная утечка памяти EventEmitter. в [NativeConnection] добавлено 11 подключенных прослушивателей. Используйте emitter.setMaxListeners() для увеличения лимита. Я не хочу подавлять предупреждение, добавляя больше прослушивателей событий, поскольку я не думаю, что требуется больше прослушивателей. Когда я внимательно изучаю журнал, я вижу, что приложение node никогда не завершается, и событие завершения процесса никогда не запускается. Ссылка на журнал находится в конце этого поста. Ниже приведен код, который я использую для различных событий. Обратите внимание, что события запускаются в двух областях в коде webhook: (1) в намерении приветствия по умолчанию (для раннего подключения к БД, чтобы гарантировать, что данные будут быстро отправлены в БД позже, когда это необходимо) и (2) в функции database_request, которая вызывается в самом последнем намерении, когда пользователь подтверждает свой выбор.
Я подозреваю, что в коде для события завершения процесса может быть ошибка, которая удаляет слушателей в конце. Но два сообщения в коде события завершения процесса никогда не регистрируются. Кто-нибудь может сообщить мне, что не так с моим кодом? Заранее спасибо.
function DefaultWelcomeIntent(agent){
console.log("mongoose.connection.readyState: ",mongoose.connection.readyState);
if (mongoose.connection.readyState !== 1) {
mongoose.connect(dbURI,{ useUnifiedTopology: true ,useNewUrlParser: true}, () => {
console.log("Mongoose state: ", mongoose.connection.readyState);
})
.catch((e) => {
console.log("catch error: ", e);
});
}
mongoose.connection.on('connected', function () {
console.log("Mongoose is connected");
});
mongoose.connection.on('disconnected', function () {
console.log("Mongoose is disconnected");
process.exit(1);
});
mongoose.connection.on('error', function (err) {//any error
console.log('Mongoose connection error: ', err);
process.exit(1);
});
process.on('SIGINT', function () {
console.log("app is terminating");
mongoose.connection.close(function () {
console.log('Mongoose default connection closed');
mongoose.connection.removeAllListeners();
process.exit(0); // terminates a node js process with 'success code'.
});
});
// some additional code in welcome intent to respond to user
}
function database_request1(context_parameters) {
if (mongoose.connection.readyState !== 1) {
mongoose.connect(dbURI, { useUnifiedTopology: true ,useNewUrlParser: true},() => {
console.log("Mongoose state: ", mongoose.connection.readyState);
})
.catch((e) => {
console.log("catch error: ", e);
});
}
mongoose.connection.on('connected', function () {
console.log("Mongoose is connected");
});
mongoose.connection.on('disconnected', function () {
console.log("Mongoose is disconnected");
process.exit(1);
});
mongoose.connection.on('error', function (err) {
console.log('Mongoose connection error: ', err);
process.exit(1);
});
process.on('SIGINT', function () {
console.log("app is terminating");
mongoose.connection.close(function () {
console.log('Mongoose default connection closed');
mongoose.connection.removeAllListeners();
process.exit(0);
});
});
// some additional code to save data to DB
}
Комментарии:
1. Где этот код расположен в остальной части вашего кода? На первый взгляд, это звучит так, как будто оно вызывается каждый раз, когда вы получаете запрос Dialogflow или что-то подобное.
2. @Prisoner спасибо за ваш комментарий. Я обновил свой приведенный выше код, чтобы показать, где вызываются эти события. Они вызываются только в двух областях: в намерении приветствия и в функции, которая вызывается в конце для сохранения данных в DB.
3. Вы не должны устанавливать новое подключение к базе данных при каждом запросе. Вместо этого вы должны создать подключение к базе данных один раз при запуске, а затем использовать это же соединение в остальной части вашего кода. Ваш драйвер базы данных обычно обрабатывает пул соединений и т.д. Внутри
4. @slebetman спасибо, я обновил приведенный выше код, чтобы показать, что я создаю соединение только при запуске, а затем в конце, когда данные передаются в базу данных.