gpt4 book ai didi

javascript - 下载多个SFTP文件时NodeJS报错 "Possible EventEmitter memory leak detected. 11 error listeners added"

转载 作者:搜寻专家 更新时间:2023-10-31 23:23:06 39 4
gpt4 key购买 nike

使用 ssh2-sftp-client 库从 SFTP 站点下载多个文件时出现错误。抛出的错误似乎表明 Node 流在每次下载完成后都没有被清除。这导致我的应用程序发生内存泄漏。在生产环境中,我需要能够下载数千个文件,因此这种内存泄漏非常严重。如何关闭流以便在下载每个文件后释放内存?

代码:

const Client = require('ssh2-sftp-client');

const sftp = new Client();
sftp.connect({
host: '195.144.107.198',
port: 22,
username: 'demo',
password: 'password'
}).then(async () => {

const fileNames = ['readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt'];

// Loop through filenames
for (let i = 0; i < fileNames.length; i++) {

// Download all the files synchronously (1 at a time)
const fileName = fileNames[i];
await new Promise((resolve, reject) => { // <-- note the await
sftp.get(fileName, true, 'utf8').then((stream) => {
let text = '';
stream
.on('data', (d) => { text += d; })
.on('end', () => {
console.log('Success downloaded file', i);
resolve(text);
});
}).catch((err) => {
console.log('Error downloading file', err);
reject(err.message)
});
});
}
sftp.end();
});

注意:此代码使用公共(public) SFTP 站点,因此凭据不敏感,您可以运行它进行测试。在这里找到:https://www.sftp.net/public-online-sftp-servers

错误(下载文件 #9 后发生):

(node:44580) MaxListenersExceededWarning: Possible EventEmitter memory leak detected.
11 error listeners added. Use emitter.setMaxListeners() to increase limit

最佳答案

所以你说你正试图在 prod 中下载数千个文件,但你正在为每个文件使用一个监听器。 Node 只允许您在触发警报之前创建最多 10 个事件监听器。

参见:

https://nodejs.org/dist/latest-v8.x/docs/api/events.html#events_eventemitter_defaultmaxlisteners https://github.com/nodejs/help/issues/1051

如果您想纠正这个问题,我建议您实现一个队列,并且一次只下载 10 个文件。

类似于:

const Client = require('ssh2-sftp-client');

const sftp = new Client();
sftp.connect({
host: '195.144.107.198',
port: 22,
username: 'demo',
password: 'password'
}).then(async () => {

// Treat files array as a queue instead of an array
const fileQueue = ['readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt', 'readme.txt'];

// Use this function to grab files from your main files array
const downloadFilesFromQueue = (fileName) =>
new Promise((resolve, reject) => {

// Sanity check
if(!fileName) {
resolve();
}

sftp.get(fileName, true, 'utf8').then((stream) => {
let text = '';
stream
.on('data', (d) => { text += d; })
.on('end', () => {
console.log('Success downloaded file', fileName);
resolve(text);
});
}).catch((err) => {
console.log('Error downloading file', err);
reject(err.message);
});
})

// Handle errors
.catch((err) => console.log(err.message))

// Get next file from the queue
.then(() => {

// If there are no more items in the queue, we're done
if (!fileQueue.length) {
return;
}

downloadFilesFromQueue(fileQueue.shift())
});

// Track all unresolved promises
const unresolvedPromises = [];

// Request no more than 10 files at a time.
for (let i = 0; i < 10; i++) {

// Use file at the front of the queue
const fileName = fileQueue.shift();

unresolvedPromises.push(downloadFilesFromQueue(fileName));
}

// Wait until the queue is emptied and all file retrieval promises are
// resolved.
await Promise.all(unresolvedPromises);

// done
sftp.end();
});

关于javascript - 下载多个SFTP文件时NodeJS报错 "Possible EventEmitter memory leak detected. 11 error listeners added",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52825092/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com