Firebase 函数 Node.js 转换流

Posted

技术标签:

【中文标题】Firebase 函数 Node.js 转换流【英文标题】:Firebase function Node.js transform stream 【发布时间】:2021-01-22 12:50:29 【问题描述】:

我正在创建一个 Firebase HTTP 函数,它进行 BigQuery 查询并返回查询结果的修改版本。该查询可能会返回数百万行,因此在响应 HTTP 客户端之前,我无法将整个查询结果存储在内存中。我正在尝试使用 Node.js 流,并且由于我需要在将结果发送到客户端之前对其进行修改,因此我正在尝试使用转换流。但是,当我尝试通过我的转换流传输查询流时,Firebase 函数崩溃并显示以下错误消息:finished with status: 'response error'

我的最小可重现示例如下。我正在使用缓冲区,因为我不想一次处理单行(块),因为我需要进行异步网络调用来转换数据。

return new Promise((resolve, reject) => 
    const buffer = new Array(5000)
    let bufferIndex = 0
    const [job] = await bigQuery.createQueryJob(options)
    const bqStream = job.getQueryResultsStream()

    const transformer = new Transform(
        writableObjectMode: true,
        readableObjectMode: false,
        transform(chunk, enc, callback) 
            buffer[bufferIndex] = chunk
            if (bufferIndex < buffer.length - 1) 
                bufferIndex++
            
            else 
                this.push(JSON.stringify(buffer).slice(1, -1)) // Transformation should happen here.
                bufferIndex = 0
            
            callback()
        ,
        flush(callback) 
            if (bufferIndex > 0) 
                this.push(JSON.stringify(buffer.slice(0, bufferIndex)).slice(1, -1))
            
            this.push("]")
            callback()
        ,
    )

    bqStream
        .pipe(transform)
        .pipe(response)

    bqStream.on("end", () => 
        resolve()
    )

【问题讨论】:

【参考方案1】:

在响应 HTTP 客户端之前,我无法将整个查询结果存储在内存中

不幸的是,在使用 Cloud Functions 时,这正是必须发生的事情。

响应负载的documented 限制为 10MB,当您的代码继续写入响应时,它有效地存储在内存中。不支持请求和响应的流式传输。

另一种方法是将您的响应写入 Cloud Storage 中的对象,然后将对该文件的链接或引用发送到客户端,以便客户端可以从该对象中完整读取响应。

如果您需要发送大量流式响应,Cloud Functions 不是一个好的选择。 Cloud Run 也同样受到限制。您将需要研究允许直接套接字访问的其他解决方案,例如 Compute Engine。

【讨论】:

哦,这就解释了为什么在本地模拟函数时它工作得很好,但在部署它之后就不行了。我会考虑将其流式传输到 Cloud Storage 并重定向到该文件。 如果此回复有帮助,请点赞/接受。这有助于社区确定接受的答案。

以上是关于Firebase 函数 Node.js 转换流的主要内容,如果未能解决你的问题,请参考以下文章

javascript 简单的Node.js转换流

如何在node js中将promise转换为回调?

将 node.js 缓冲区转换为字符串,然后转换为 JSON

如何在 Node JS 中将原始 PCM 流转换为 Discord 机器人的 opus 或 wav 流?

如何使用 node.js 将 .pcm 文件转换为 wav 文件?

将 Node.js 流错误事件传播到异步等待样式代码