微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Firebase函数Node.js转换流

如何解决Firebase函数Node.js转换流

我正在创建一个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()
    })
}

解决方法

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

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

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

一种选择是将您对云存储中的对象的响应写入,然后将对该文件的链接或引用发送给客户端,以便客户端可以从该对象中完全读取响应。

如果您需要发送大量流式响应,则“云功能”不是一个不错的选择。同样没有限制的Cloud Run也是如此。您将需要研究其他允许直接套接字访问的解决方案,例如Compute Engine。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。