Firebase 存储与云函数 - ECONNRESET [英] Firebase Storage & Cloud Functions - ECONNRESET

查看:22
本文介绍了Firebase 存储与云函数 - ECONNRESET的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开发了一个 Firebase Cloud 函数,用于处理对上传图像的多项操作.我的代码基于 这篇文档文章这个云函数示例.因此,它使用 Google 云存储包.

I developed a Firebase Cloud function that processes several manipulations on uploaded images. My code is based on this documentation article and this Cloud Function example. Hence, it is using Google Cloud Storage package.

它几乎一直运行良好,但有时在上传到存储或从存储中删除时会出现此错误:

It is working fine almost all the time, but sometimes I am getting this error when uploading to or deleting from Storage :

 Error: read ECONNRESET
    at exports._errnoException (util.js:1026:11)
    at TLSWrap.onread (net.js:569:26)

我正在使用我的应用程序的默认存储桶,由 event.data.bucket 引用.

I am using the default bucket of my application, referenced by event.data.bucket.

如果您需要其他信息或代码片段,请告诉我,即使我的代码非常接近我之前链接的函数示例.

Let me know if you need additional information or code snippets, even if my code is really close to the Function example I linked before.

我找到了 这个 GitHub 问题,但我确认我正在返回每次的承诺.例如,这里是触发错误的删除部分:

I found this GitHub issue, but I checked that I am returning a promise everytime. For example, here is the deletion part that triggers the error :

index.js

exports.exampleFunction = functions.storage.object().onChange(event => {
    return f_thumbnails.exampleFunction(event);
});

example_function.js

module.exports = exports = function (_admin, _config) {
    admin = _admin;
    config = _config;

    return {
        "exampleFunction": function (event) {
            return exampleFunction(event);
        }
    };
};

const exampleFunction = function (event) {
    const gcsSourceFilePath = event.data.name;
    const gcsSourceFilePathSplit = gcsSourceFilePath.split('/');
    const gcsBaseFolder = gcsSourceFilePathSplit.length > 0 ? gcsSourceFilePathSplit[0] : '';
    const gcsSourceFileName = gcsSourceFilePathSplit.pop();
    const gceSourceFileDir = gcsSourceFilePathSplit.join('/') + (gcsSourceFilePathSplit.length > 0 ? '/' : '');

    // Not an image
    if (!event.data.contentType.startsWith('image/')) {
        console.log('Not an image !');
        return;
    }

    // Thumbnail
    if (gcsSourceFileName.startsWith(config.IMAGES_THUMBNAIL_PREFIX)) {
        console.log('Thumbnail !');
        return;
    }

    const bucket = gcs.bucket(event.data.bucket);
    const gcsThumbnailFilePath = gceSourceFileDir + config.IMAGES_THUMBNAIL_PREFIX + gcsSourceFileName;


    // File deletion
    if (event.data.resourceState === 'not_exists') {
        console.log('Thumbnail deletion : ' + gcsThumbnailFilePath);
        return bucket.file(gcsThumbnailFilePath).delete().then(() => {
            console.log('Deleted thumbnail ' + gcsThumbnailFilePath);
        });
    }
    ...

推荐答案

这似乎与google-cloud-node库对socket的处理,以及Cloud Functions中默认的socket timeout有关环境.

This seems to be related to the google-cloud-node library's handling of sockets, and the default socket timeout in the Cloud Functions environment.

用户验证的一种解决方案是修改库调用 requests 的方式,通过指定 forever: false 来不让套接字永远打开,例如.

One solution verified by a user is to modify the way the library invokes requests, to not keep the socket open forever by specifying forever: false, eg.

var request = require('request').defaults({
  timeout: 60000,
  gzip: true,
  forever: false,
  pool: {
    maxSockets: Infinity
  }
});

这是硬编码在 packages/common/src/utils.js,因此您需要将修改后的库的副本提供到您的项目中,而不是将其作为 NPM 依赖项包含在内.请参阅相关公开问题了解有关该问题的更多详细信息以及带有已应用补丁.

This is hardcoded in packages/common/src/utils.js, so you'll need to vendor a copy of the modified library into your project rather than include it as an NPM dependency. See the related public issue for more details on the issue and a link to a fork with the patch applied.

这篇关于Firebase 存储与云函数 - ECONNRESET的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆