上传文件时超出重试限制

时间:2019-04-18 13:58:23

标签: javascript node.js google-cloud-storage

上下文:我正在研究使用读取流从SFTP服务器下载文件并使用Node.js v10.15.3。通过writeStream将文件上传到GCS的代码。

由于我正在使用的SFTP库中有一个错误,stream.pipe(也就是说,从该库产生的读取流中进行管道传输)实际上在节点10中被破坏了,因此,我尝试改为通过以下代码上传该文件(其中stream是读取流,而不必要的信息已被删除):

let acl = fileMode;
if (fileMode === 'public') {
    // options for acl are publicRead and private
    // need to add the Read if public
    acl += 'Read';
}
var options = {
    predefinedAcl: acl,
    destination: destPath,
    metadata: {
        contentType: contentType,
        cacheControl: 'no-cache'
    }
};
// Add in a check here for if the bucket exists
let file = new File(bucket, destPath);
let writeStream = file.createWriteStream(options);
writeStream.on('finish', () => {
    file.getMetadata()
        .then((metadata) => {
            console.log('metadata', metadata);
            return resolve(metadata);
        })
        .catch(error => {
            console.error('Error getting file metadata', error);
            return reject(error);
        });
});
stream.on('end', () => {
    try {
        writeStream.end();
    } catch (err) {
        console.error('Error closing writeStream', err);
        return reject(err);
    }
});
writeStream.on('error', error => {
    console.error('Error in writeStream', error);
    return reject(error);
});
stream.on('error', error => {
    console.error('Error in stream', error);
    return reject(error);
});
let data = stream.read();
while (data) {
    writeStream.write(data);
    data = stream.read();
}

当我使用while (data)方法从我们的SFTP服务器流式传输到文件系统上的本地文件时,此方法可以正常工作。但是,当我尝试运行此代码以将其上传到我们的GCS文件时,出现以下错误:

MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 close listeners added. Use emitter.setMaxListeners() to increase limit
Error in writeStream Error: Retry limit exceeded
// stacktrace omitted
Error Uploading to GCS from a stream: Retry limit exceeded
    Error: Retry limit exceeded

似乎我在这里一定做错了什么,但是我不知道为什么这不是一个有效的方法,也不知道我是否丢失了一些细微的流(我自由地坦白说,黑匣子)或GCS问题。

编辑:好的,这似乎与SFTP问题完全无关。我已经尝试过使用推荐的方法从本地fs上传文件,并且看到了相同的错误。我正在尝试的更“简化”的代码是:

// Add in a check here for if the bucket exists
let file = new File(bucket, destPath);

fs.createReadStream('sample_file.csv')
    .pipe(file.createWriteStream(options))
    .on('error', function(err) {
        console.error('err', err);
        return reject(err);
    })
    .on('finish', function() {
        console.log('resolving');
        return resolve({gcsUrl: url});
    });

2 个答案:

答案 0 :(得分:1)

Alex Riquelme正确指出,当您在Node.js中的事件超过maximum default listeners时,将发生此警告。默认情况下,Node.js中事件的侦听器的最大数量为10。您可以更改此值,但是在这种情况下不建议这样做,因为这仍会浪费资源,因此会浪费资源。 / p>

要在GCS中创建多个侦听器来上传文件的原因是,默认情况下,createWriteStream中启用了可恢复的上传。对于您的情况,由于要上传许多小文件,建议的方法是将options.resumable设置为false。这样,您就可以避免由于可恢复的上传而导致的开销,而不必允许创建更多的侦听器。

答案 1 :(得分:0)

此警告实际上是预期的。当您尝试将文件上传到GCS时,它将尝试优化此上传,并且会将您的文件拆分为多个块(通常为1MB的块)。因此,它将创建多个侦听器以上传此文件。默认情况下,Node.js中的侦听器的最大数量为10(请看this documentation)。如果要将监听器的数量设置为无限制,只需将变量setMaxListeners(0);设置为0