Превышен лимит попыток при загрузке файла - PullRequest
0 голосов
/ 18 апреля 2019

Контекст: я работаю над кодом, который использует поток чтения для загрузки файла с SFTP-сервера и загрузки его в GCS через writeStream, используя Nodejs v10.15.3.

Из-за ошибки в библиотеке 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. Я попытался просто загрузить файл с локальной файловой системы, используя рекомендуемый метод, и вижу ту же ошибку. Более «обтекаемый» код, который я пытаюсь использовать:

// 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 ]

1 голос
/ 07 мая 2019

Как правильно указал Алекс Рикельме , это предупреждение возникает, когда вы превышаете максимальное число прослушивателей по умолчанию для события в Node.js. Максимальное количество прослушивателей для события в Node.js по умолчанию равно 10. Вы можете изменить это значение, однако в этой ситуации это не рекомендуется, поскольку это будет пустой тратой ресурсов, поскольку утечка все еще будет.

Причина, по которой будет создано несколько прослушивателей для загрузки файлов в GCS, заключается в том, что возобновляемые загрузки включены по умолчанию в createWriteStream . В вашем случае, когда вы загружаете много маленьких файлов, рекомендуется установить options.resumable в false. Таким образом вы избежите накладных расходов, вызванных возобновляемой загрузкой, без необходимости создания большего количества слушателей.

0 голосов
/ 30 апреля 2019

Это предупреждение действительно ожидается. Когда вы пытаетесь загрузить файл в GCS, он попытается оптимизировать загрузку и разделит ваш файл на куски (обычно на куски по 1 МБ). Таким образом, он создаст несколько слушателей для загрузки этого файла. По умолчанию максимальное число слушателей в Node.js составляет 10 (посмотрите на эту документацию ). если вы хотите установить неограниченное количество слушателей, просто установите переменную setMaxListeners(0); в 0

...