ECONNRESET 套接字挂起

ECONRESET socket hungup

我有一个在 firebase 数据库 onWrite 上触发的函数。函数体使用两个 google 云 api(DNS 和存储)。

虽然函数是 运行 并且按预期工作(大部分),但问题是 Socket 挂断的频率比我希望的要高。 (50%~ 次)

我的问题是: 它与其他测试人员所经历的相似吗?这是众所周知的突出问题还是预期行为?

示例代码如下:

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const {credentials} = functions.config().auth;
credentials.private_key = credentials.private_key.replace(/\n/g, '\n');
const config = Object.assign({}, functions.config().firebase, {credentials});
admin.initializeApp(config);
const gcs = require('@google-cloud/storage')({credentials});
const dns = require('@google-cloud/dns')({credentials});
const zoneName = 'applambda';
const zone = dns.zone(zoneName);

exports.createDeleteDNSAndStorage = functions.database.ref('/apps/{uid}/{appid}/name')
.onWrite(event => {
    // Only edit data when it is first created.
    const {uid, appid} = event.params;
    const name = event.data.val();
    const dbRef = admin.database().ref(`/apps/${uid}/${appid}`);

    if (event.data.previous.exists()) {
        console.log(`already exists ${uid}/${appid}`);
        return;
    }
    // Exit when the data is deleted.
    if (!event.data.exists()) {
        console.log(`data is being deleted ${uid}/${appid}`);
        return;
    }

    const url = `${name}.${zoneName}.com`;
    console.log(`data: ${uid}/${appid}/${name}\nsetting up: ${url}`);

    setupDNS({url, dbRef});
    setupStorage({url, dbRef});
    return;
});

function setupDNS({url, dbRef}) {

    // Create an NS record.
    let cnameRecord = zone.record('cname', {
        name: `${url}.`,
        data: 'c.storage.googleapis.com.',
        ttl: 3000
    });

    zone.addRecords(cnameRecord).then(function() {
        console.log(`done setting up zonerecord for ${url}`);
        dbRef.update({dns: url}).then(res => console.log(res)).catch(err => console.log(err));
    }).catch(function(err) {
        console.error(`error setting up zonerecord for ${url}`);
        console.error(err);
    });
}

function setupStorage({url, dbRef}) {
    console.log(`setting up storage bucket for ${url}`);

    gcs.createBucket(url, {
        website: {
            mainPageSuffix: `https://${url}`,
            notFoundPage: `https://${url}/404.html`
        }
    }).then(function(res) {
        let bucket = res[0];
        console.log(`created bucket ${url}, setting it as public`);
        dbRef.update({storage: url}).then(function() {
            console.log(`done setting up bucket for ${url}`);
        }).catch(function(err) {
            console.error(`db update for storage failed ${url}`);
            console.error(err);
        });
        bucket.makePublic().then(function() {
            console.log(`bucket set as public for ${url}`);
        }).catch(function(err) {
            console.error(`setting public for storage failed ${url}`);
            console.error(err);
        });
    }).catch(function(err) {
        console.error(`creating bucket failed ${url}`);
        console.error(err);
    });
}

我认为您的函数需要 return 一个承诺,以便所有其他异步工作有时间在函数关闭之前完成。正如现在所示,您的函数只需立即 returns,无需等待工作完成。

我不太了解您使用的云 API,但我猜您应该兑现 setupDns()setupStorage() return 来自他们正在做的异步工作,然后 return Promise.all() 传递这两个承诺让 Cloud Functions 知道它应该等到所有工作完成后再清理 运行 函数的容器.