Задать вопрос
@n1ksON
мидл

Как избавиться от утечки памяти в NodeJS?

Имеется код для телеграм-бота, написанный на nodejs + telegraf (+ node-fetch).
На сервере возникает ошибка:
(node:215439) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added to [TLSSocket]. Use emitter.setMaxListeners() to increase limit
MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added to [TLSSocket]. Use emitter.setMaxListeners() to increase limit
    at _addListener (events.js:389:17)
    at TLSSocket.addListener (events.js:405:10)
    at TLSSocket.Readable.on (_stream_readable.js:873:35)
    at ClientRequest.<anonymous> (/home/httpd/url.com/folder/node_modules/telegraf/node_modules/node-fetch/lib/index.js:1529:7)
    at ClientRequest.emit (events.js:326:22)
    at tickOnSocket (_http_client.js:709:7)
    at onSocketNT (_http_client.js:750:5)
    at processTicksAndRejections (internal/process/task_queues.js:84:21)


Экспериментальным путем выяснил, что утечка возникает в следующем коде:
const showResult = async (ctx) => {
  await ctx.replyWithAnimation(contentArray[1][indexes.gif], {
    caption: contentArray[1][indexes.title].replace(/(?:-|_|\.|!)/gm, ' '),
    parse_mode: 'MarkdownV2',
    ...Markup.inlineKeyboard([
      Markup.button.url('click', contentArray[1][indexes.link] + params)
    ])
  })
  await ctx.replyWithAnimation(contentArray[2][indexes.gif], {
    caption: contentArray[2][indexes.title].replace(/(?:-|_|\.|!)/gm, ' '),
    parse_mode: 'MarkdownV2',
    ...Markup.inlineKeyboard([
      Markup.button.url('click', contentArray[2][indexes.link] + params)
    ])
  })
}

Мне нужно отправить несколько сообщений в чат, а после отправки всех, то есть в промисе функции showResult, вывести финальное сообщение.
Для этого я добавил async/await на вывод сообщений, чтоб финальное сообщение всегда выводилось после них. Без async/await финальное сообщение может выводится не последним, а раньше. Я так понимаю, что запросы на отправку сообщений в бота сами по себе асинхронны, поэтому выводятся непоследовательно, следовательно и финальное сообщение может отправиться раньше, чем какое-нибудь другое

Но из-за навешивания async/await на отправку сообщений возникает утечка памяти. Как правильно реализовать желаемое без утечек?
  • Вопрос задан
  • 743 просмотра
Подписаться 1 Простой Комментировать
Пригласить эксперта
Ответы на вопрос 1
@vshvydky
MaxListenersExceededWarning говорит о том что воможно у тебя в коде идет бесконечная подписка на событие эвент эмиттера, если это не предусмотрено по коду, потенциально это может быть утечкой памяти
The --trace-warnings command-line flag can be used to display the stack trace for such warnings.

The emitted warning can be inspected with process.on('warning') and will have the additional emitter, type, and count properties, referring to the event emitter instance, the event's name and the number of attached listeners, respectively. Its name property is set to 'MaxListenersExceededWarning'.


если это корректное число подписок то emitter.setMaxListeners весьма элегантно перестанет выдавать варнинг
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы