Тайм-аут функции Firebase при передаче потока клиенту
На сервере я хочу преобразовать HTML в PDF, передать его обратно клиенту и затем загрузить файл.
Изолированный - не использующий Firebase Hosting или Functions - у меня есть простой Node/Express Server со следующей конечной точкой POST (с использованием промежуточного программного обеспечения Body Parser):
app.post('/download', (req, res) => {
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-disposition': 'attachment; filename=Report.pdf'
});
const options = { format: 'letter' };
pdf.create(req.body.template, options).toStream((err, stream) => {
if (err) res.send(err);
const watchdog = stream.pipe(res);
watchdog.on('finish', () => {
console.log('Finish event emitted');
res.end();
});
});
});
Обратите внимание, что это должен быть маршрут POST - по причинам, выходящим за рамки этого вопроса.
На клиенте я могу довольно легко получить этот поток, создать URL-адрес Blob, а затем загрузить файл, программно щелкнув по тегу привязки:
const headers = new Headers();
headers.append('Content-Type', 'application/json');
const data = { template: '<h1>This is my data sent from the client!</h1>'};
fetch('/download', {
method: "POST",
mode: "cors",
headers,
body: JSON.stringify(data)
})
.then(response => response.body)
.then(body => {
const reader = body.getReader();
return new ReadableStream({
start(controller) {
return pump();
function pump() {
return reader.read().then(({ done, value }) => {
if (done) {
controller.close();
return;
}
controller.enqueue(value);
return pump();
})
}
}
})
})
.then(stream => new Response(stream))
.then(response => response.blob())
.then(blob => URL.createObjectURL(blob))
.then(url => {
const link = document.createElement('a');
link.href = url;
link.download = "Report.pdf";
link.click();
})
.catch(err => console.log(err));
В моей изолированной среде тестирования это работает фантастически и занимает всего около трех секунд.
Когда я пытался перейти с моего тестового сервера на Firebase Cloud Functions, проблемы возникали сами собой. В Firebase Functions я использую точно такой же маршрут POST, я просто включаю CORS и устанавливаю экспорт:
const cors = require('cors');
app.use(cors({ origin: true })); // Will change in production.
// Exact same POST Route as above - no changes in code.
exports.app = functions.https.onRequest(app);
На клиенте я делаю точно такой же запрос Fetch POST, единственной дельтой является другой URL:
fetch('https://us-central1-[my-project-id].cloudfunctions.net/app/download',{
// Same code as above for client.
});
Однако при развертывании приложения я не получаю ответ, и время от времени запрос прерывается. Сегодня я вызывал эту функцию всего несколько раз и все еще использовал свободную квоту. Даже используя return stream.pipe(res)
не работает в функции. Я заметил, что все запросы истекают, и функция, кажется, продолжает вызывать себя, как если бы она была рекурсивной.
Я был бы очень признателен за любую помощь в понимании того, почему код отлично работает на моем локальном сервере с Node/Express, но не работает при переходе на Firebase Functions.